威尼斯人线上娱乐

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

25 3月 , 2019  

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

总结

上述就是那篇小说的全体内容了,希望本文的内容对我们的就学大概办事能带来一定的扶植,假设有疑问大家能够留言沟通,多谢大家对帮客之家的援救。

参考

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)
  • 下边包车型客车函数也就是调用了3个函数

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

  • 能够通过给getattr(module,arrtib,def)设置暗中认可值,幸免报错

  • 反射函数

    • getattr():获取属性
    • delattr():删除属性
    • Python中用字符串调用函数或艺术言传身教代码,内建函数getattr工厂方式。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. 可是假如网站太大了,全体的格局都写在一个模块里面,维护起来会很辛劳,同时反射获取格局需求更长的时刻
    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)
      
      • 能够将另行的变量作为靶子的质量:
        • 把参数赋值给指标,在措施中调用–封装

      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,那样方法的参数重复且调用的时候很麻烦,即使把它们都打包到对象里,直接在指标里调用,那样重复的参数只须求穿2次即可.
      • 包装步骤

        • 地点的包装进度不够好,因为假使外人看你的代码,旁人不必然知道调用方法前必要封装数据,能够优化为:
        • 创造对象时会调用构造方法__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

Demo:3个模块支持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学习沟通1,2群已满.

本条例子中能够依照传入output函数的format参数的不一样去调用statsout模块不一致的主意(用格式化字符串完成output_%s)

Linux and
python学习交换3群新开,欢迎出席,一起学习.qq 3群:563227894

参考资料:

不前进,不倒退,结束的动静是不曾的.

Python找这一个的getattr()函数详解

一块发展,与君共勉,

python2.7文档

熟稔getattr的相应了解,getattr(a,
‘b’)的功效就和a.b是均等的
那么那个内建函数有怎么样成效吗,最有利的确凿是使用它来贯彻工厂…


相关文章

发表评论

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

网站地图xml地图