Python中用字符串调用函数或情势言传身教代码,内建函数getattr工厂方式

by admin on 2019年4月3日

getattr()这些方法最首要的坚守是促成反射机制。也正是说能够经过字符串获取方式实例。  传入不一致的字符串,调用的不二诀窍不一致。

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

前言

本文首要给大家介绍了有关Python用字符串调用函数或格局的相干内容,分享出来供大家参考学习,上面来一起看看详细的牵线:

先看三个事例:

>>> 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的七个放置函数,通过它们得以一字典的主意访问一些和全局变量。

getattr()

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

返回 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()

总结

上述便是那篇著作的全体内容了,希望本文的内容对大家的上学可能办事能带来一定的帮手,假如有疑难大家能够留言调换,多谢大家对帮客之家的支撑。

bf88必发唯一官网,参考

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():删除属性
    • Python中用字符串调用函数或情势言传身教代码,内建函数getattr工厂方式。hasattr():判断进行是不是留存
    • setattr():添加或修改属性
  • python中,一切皆对象,通过反射,依据字符串去对象中(模块,类)获取元素

  • 扩展

    • 通过__import__()导入的模块假使存在的途径为:lib\Python中用字符串调用函数或情势言传身教代码,内建函数getattr工厂方式。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. 而是只要网址太大了,全部的法门都写在二个模块里面,维护起来会很麻烦,同时反射获取格局必要更长的大运
    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>
    
    • 封装:

      • 若果二个类中七个办法要求用到同2个参数,每趟都穿的话,太费事

      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)
      
      • 能够将再也的变量作为对象的性能:
        • 把参数赋值给指标,在章程中调用–封装

      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学习调换一,二群已满.

那么些事例中能够依照传入output函数的format参数的分裂去调用statsout模块差别的法子(用格式化字符串达成output_%s)

Linux and
python学习调换三群新开,欢迎加入,1起学习.qq 3群:5632278九四

参考资料:

不前进,不倒退,结束的情景是一直不的.

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

联机前进,与君共勉,

python2.7文档

熟知getattr的相应明了,getattr(a,
‘b’)的功力就和a.b是1样的
那么这么些内建函数有啥样效益呢,最便宜的真切是行使它来实现工厂…

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图