【www.5929.com】面向对象,Python中用字符串调用函数或艺术言传身教代码

getattr()那些办法最重大的成效是贯彻反射机制。相当于说能够通过字符串获取方式实例。  传入分化的字符串,调用的不二秘诀不相同等。

Python中用字符串调用函数或措施言传身教代码,python示例代码

前言

正文首要给我们介绍了有关Python用字符串调用函数或艺术的连带内容,分享出去供大家参考学习,上面来一块探访详细的介绍:

先看3个例证:

>>> def foo():
    print "foo"

>>> def bar():
    print "bar"

>>> func_list = ["foo","bar"]
>>> for func in func_list:
    func()
TypeError: 'str' object is not callable

咱俩愿意遍历执行列表中的函数,不过从列表中收获的函数名是字符串,所以会指示类型错误,字符串对象是不得以调用的。假使我们想要字符串变成可调用的靶子呢?或是想透过变量调用模块的属性和类的属性呢?

以下有二种办法能够达成。

eval()

>>> for func in func_list:
    eval(func)()
foo
bar

eval()
平常用来施行二个字符串表达式,并回到表明式的值。在此处它将字符串转换到对应的函数。eval()
功效强大不过比较危险(eval is evil),不提出选用。

locals()和globals()

>>> for func in func_list:
    locals()[func]()
foo
bar

>>> for func in func_list:
    globals()[func]()
foo
bar

locals() 和 globals()
是python的八个放置函数,通过它们能够一字典的不二等秘书籍访问1些和全局变量。

getattr()

getattr() 是 python 的内建函数,getattr(object,name) 就一定于
object.name,不过此间 name 可以为变量。

【www.5929.com】面向对象,Python中用字符串调用函数或艺术言传身教代码。返回 foo 模块的 bar 方法

>>> import foo
>>> getattr(foo, 'bar')() 

回来 Foo 类的天性

>>> class Foo:
  def do_foo(self):
    ...

  def do_bar(self):
    ...

>>> f = getattr(foo_instance, 'do_' + opname)
>>> f()

【www.5929.com】面向对象,Python中用字符串调用函数或艺术言传身教代码。总结

上述正是那篇小说的全体内容了,希望本文的内容对我们的读书恐怕办事能带来一定的援救,若是有疑难我们能够留言交换,谢谢咱们对帮客之家的支撑。

参考

Calling a function of a module from a string with the function’s name in
Python

How do I use strings to call functions/methods?

前言
本文主要给大家介绍了有关Python用字符串调用函数或艺术的连锁内容,分享…

反射

  • 反射:
    1. 通过字符串的花样导入模块
    2. 因此字符串的样式去模块中寻找制定的积极分子(属性、函数),并行使

# 1.创建index.py主程序
# 2.创建commoms模块提供函数
# 3.引入commons模块调用模块中的函数

# commoms.py
def f1():
    print('F1')
    return 'F1'

# index.py
import commons
if __name__ == '__main__':
    ret = commons.f1()
    print(ret) # F1
  • 上面的函数是不荒谬导入并推行,假设想导入用户输入的模块名,并调用用户输入的函数,则:

# index.py
if __name__ == '__main__':
    module = input('请输入模块名:')
    mod = __import__(module)
    # ret = mod.f1() # 正常调用
    # print(ret) # 正常输出
    attr = input('请输入方法名:')
    meth = getattr(mod,attr)
    ret = meth()
    print(ret)
  • 地点的函数也便是调用了一个函数

    • __import__():通过字符串导入模块对象
    • getattr(module,attr):获取模块里的成分
  • 实质上getattr()函数才叫反射,通过字符串的款式在模块中检索对应的因素,假如成分不设有,则报错.

  • 可以透过给getattr(module,arrtib,def)设置私下认可值,幸免报错

  • 反射函数

    • getattr():获取属性
    • delattr():删除属性
    • hasattr():判断进行是或不是存在
    • setattr():添加或涂改属性
  • python中,壹切皆对象,通过反射,依照字符串去对象中(模块,类)获取成分

  • 扩展

    • 通过__import__()导入的模块借使存在的门路为:lib\modules\moudle.py
    • 倘若导入的法子为:__import__(‘lib.modules.moudle’),则导入的为lib文件夹
    • 比方想化解这几个题材,导入的章程为:__import__(‘lib.modules.moudle’,
      fromlist=True)

难题聚焦:

原型:getattr(对象,方法名)

基于反射模拟web框架路由系统

  • 依据用户发送区别的url,服务器执行差别的操作,再次回到不一样的结果
  • 原来操作:
    1. 截取url最终的字段,如login,logout,pay等
    2. 经过if,elif,else判断字段,然后实施模块里面包车型客车格局
  • 优化:
    1. 壹旦网址非常大,有为数不少个格局,都要if,elif,else来判定,则必要写大批量的判断代码
    2. 因而反射来获得相应的不贰秘籍,然后调用,则足以绝不修改index.py方法,只须求在模块里面添加响应的方法,让url中的字段去相配
  • 完善:
    1. 可是只要网址太大了,全体的章程都写在3个模块里面,维护起来会很辛勤,同时反射获取方式须要更加长的年月
    2. 透过分模块来管理差别功效的办法,在url中把模块和方式名都加上,切割后通过__import__(path,
      fromlist = True)来导入模块,通过反射获取格局

# 1.创建主程序index.py
# 2.创建功能模块
# 3.截取url,获取里面的地址参数执行不同的方法

# url = input("请输入url:")
url = 'www.yuhhcompany.com/account/login'
regex = 'www.yuhhcompany.com'
ret = re.match(regex, url)
if ret != None:
    # 匹配成功
    host, module, method = url.split('/')
    mod = __import__(module, fromlist=True)
    if hasattr(mod, method):
        ret = getattr(mod, method)()
  • 所有的web框架:php,c#,java,Django本质都是以此道理

深谙getattr的应该掌握,getattr(a, ‘b’)的意义就和a.b是千篇一律的

那么这么些内建函数有怎样作用呢,最便利的确凿是选择它来贯彻工厂方法(Factory
Method)情势

除此以外,在回调函数里也时常利用这几个函数,对回调掌握不深,那里不再举例

 

面向对象

  • 编制程序语言:

    • java、c#只可以通过面向对象编制程序
    • Python能够透过函数式编制程序,也足以由此面向对象编制程序
  • Python面向对象:

    • class:创造类重要字
    • 概念的函数,在函数式编制程序时称函数,面向对象编程称为方法
    • 方法参数self:各类方法都须求加上self参数,值为调用该办法的指标,点用方法时python会自动传入该参数,不要求协调传

    class Cat:
        def fun1(self):
            pass
        def fun2(self):
            pass
    
    cat1 = Cat()
    cat1.fun1()
    cat1.fun2()
    
  • 格局的参数self:

    • self代表调用方法的靶子,不需求协调传入,当调用方法时,python自动帮我们传入该self参数

    class Cat:
        def fun1(self):
            print(self)
    cat1 = Cat()
    print(cat1) # <__main__.Cat object at 0x10073fc50>
    cat1.fun1() # <__main__.Cat object at 0x10073fc50>
    
    • 封装:

      • 只要1个类中八个艺术必要用到同一个参数,每一回都穿的话,太难为

      class Cat:
          def fun1(self, name, age):
              print(name, age)
          def fun2(self, name, age):
              print(name, age)
          def fun3(self, name, age):
              print(name, age)
      
      cat1 = Cat()
      cat1.fun1('yhh', 23)
      cat1.fun2('yhh', 23)
      cat1.fun3('yhh', 23)
      
      • www.5929.com ,能够将再一次的变量作为靶子的习性:
        • 把参数赋值给目的,在艺术中调用–封装

      class Cat:
          def fun1(self):
              print(self.name, self.age)
          def fun2(self):
              print(self.name, self.age)
          def fun3(self):
              print(self.name, self.age)
      
      cat1 = Cat()
      cat1.name = 'yhh'
      cat1.age = 23
      cat1.fun1()
      cat1.fun2()
      cat1.fun3()
      
      • 包裹使用处境:

        • 一而再操作数据库,对数据库的操作(curd)都亟待用到ip,port,user,password,content等,要是种种方法都传ip,port,user,passowrd,那样方法的参数重复且调用的时候很麻烦,若是把它们都打包到目的里,直接在目的里调用,那样重复的参数只须求穿一回即可.
      • 装升高骤

        • 下面的卷入进程不够好,因为只要人家看您的代码,外人不必然精通调用方法前供给封装数据,可以优化为:
        • 创建对象时会调用构造方法__init__(),对象销毁的时候会调用__del__()方法(析构方法)

      class Cat:
          def __init__(self, name, age):
              self.name = name
              self.age = age
          def fun1(self):
              print(self.name, self.age)
          def fun2(self):
              print(self.name, self.age)
          def fun3(self):
              print(self.name, self.age)
      
    • 对象系列化

      • 在python中,对象足以因而pickle系列化,然后在本土持久化,能够用来存档
      • 不可能用json,因为json只好转成python的中坚项目,自定义类不属于主旨类型

      import pickle
      
      # 存档
      with open('object.pickle', mode='wb') as file:
          pickle.dump(cat1,file)
      
      # 读档
      with open('object.pickle', mode='rb') as file:
          cat1 = pickle.load(file)
          cat1.fun1() # YHH 23
      
    • 继承

      • python中继承是急需在子类的类名后跟上:(父类类名)
      • 父类–子类
      • 基类–派生类
      • 派生类和父类有同等的办法时,以派生类为主

      class Father:
          def fun1(self):
              print('Father')
      
      class Son(Father):
          def fun2(self):
              print('Son')
      
      son = Son()
      son.fun1()  # Father
      son.fun2()  # Son
      
    • 多继承

      • java、c#只扶助单继承
      • python能够多延续
      • 假设A继承B和C,B和C都有同等的方法,则以持续时写在左边的为主,假设A也有这些方法,则以A为主
    • 多继承面试题:

    在pytho3.5中:
    # 如果继承关系
    class E(C,D):
        pass
    # A --> C --> E
    # B --> D --> E
    # E继承CD,C继承A,D即成B
    # 则调用的顺序为:E --> C --> A --> D --> B(顶层没有同一个基类)
    
    # 如果A和B同时又继承BASE基类,则调用顺序为:
    E --> C --> A --> D --> B --> BASE(顶层有同一个基类)
    python2.7不一样
    
    • 多态

      • python本身语言特色就协助多态,像java,c#等因为是强类型语言,相比较复杂

      lass Cat():
          def fun1(self):
              print('fun1')
      
      class Dog():
          def fun1(self):
              print('fun1')
      
      def function(animal):
          animal.fun1()
      
      function(Cat())
      function(Dog())
      
      • 其余语言有重载,python不支持
    • 接口

      • python语言没有接口一说
      • 接口类型:
        • 代码级别:interface
        • 工作级别:访问后台的地方

先看一下合法文书档案:

举个栗子:

getattr(object, name[, default])

pyMethod类下定义了四个法子,getattr(pyMethod(),’out%s’%str)()  
传入的章程名分歧,调用区别的章程。些处方法名称叫字符串。

Return the value of the named attribute of object. name must be a
string. If the string is the name of one of the object’s attributes, the
result is the value of that attribute. For example, getattr(x, ‘foobar’)
is equivalent to x.foobar. If the named attribute does not exist,
defaultis returned if provided, otherwise AttributeError is raised.

那样的话,想想是或不是用途很多,作者可以把艺术名配置到文件中,读取时采用getattr动态去调用。

参数表达:

#coding=utf-8

class pyMethod(object):
    def outstr(self):
        print('this is string')

    def outint(self):
        print('this is number')

    def outdate(self):
        print('this is date')


if __name__=="__main__":
    str = 'int'
    getattr(pyMethod(),'out%s'%str)()     
    str = 'str'
    getattr(pyMethod(),'out%s'%str)()
    str = 'date'
    getattr(pyMethod(),'out%s'%str)()

 

try:
    func = getattr(obj, "method")
except AttributeError:
    ...... deal
else:
    result = func(args)

// 或指定默认返回值
func = getattr(obj, "method", None)
if func:
    func(args)
 getattr(pyMethod(),'out%s'%str)()  注意pyMethod()和最后的()   这里之所以这么写pyMethod()加括号是实例化类对象,最后的括号,因为getattr函数反射后,是一个方法对象。

TypeError: 不可调用

 

func = getattr(obj, "method", None)
if callable(func):
    func(args)

运作结果:

用getattr达成工厂方法:

C:\Python27\python.exe D:/weixin/python_getattr.py
this is number
this is string
this is date

Process finished with exit code 0

德姆o:三个模块支持html、text、xml等格式的打字与印刷,依照传入的formate参数的两样,调用不一样的函数实现二种格式的输出

 

import statsout 
def output(data, format="text"):                           
    output_function = getattr(statsout, "output_%s" %format) 
    return output_function(data)

Linux and
python学习沟通一,2群已满.

本条例子中能够依照传入output函数的format参数的不等
去调用statsout模块分化的格局(用格式化字符串实现output_%s)

Linux and
python学习调换三群新开,欢迎参预,壹起学习.qq 3群:5632278玖四

参考资料:

不前进,不倒退,甘休的状态是平昔不的.

Python找那七个的getattr()函数详解

联机前进,与君共勉,

python2.7文档

熟习getattr的相应明了,getattr(a,
‘b’)的功力就和a.b是均等的
那么那个内建函数有哪些成效吗,最便利的确凿是选择它来促成工厂…

Leave a Comment.