澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

Python中用字符串调用函数或方法示例代码,内建

2019-04-26 作者:www.8455.com   |   浏览(112)

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() 日常用来实践2个字符串表明式,并再次回到表明式的值。在此间它将字符串转换到对应的函数。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)
  • 上边的函数也就是调用了1个函数

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

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

  • 反射函数

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

  • 扩展

    • 通过__import__()导入的模块若是存在的路线为:libmodulesmoudle.py
    • 假使导入的办法为:__import__('lib.modules.moudle'),则导入的为lib文件夹
    • 比如想缓和这些主题材料,导入的方式为:__import__('lib.modules.moudle', fromlist=True)

主题材料集中:

一.1.propety动态属性

在面向对象编制程序中,咱们一般把名词性的事物映射成属性,动词性的事物映射成方法。在python中他们相应的各自是性质self.xxx和类格局。但神迹大家须求的质量要求基于其余品质动态的测算,此时假设一向利用品质方法处理,会促成数据区别步。下边介绍@property方法来动态创立类属性。

from datetime import datetime,date

class User:
    def __init__(self,name,birthday):
        self.name = name
        self.birthday = birthday
        self._age = 0

    @property
    def age(self):
        return datetime.now().year - self.birthday.year

    @age.setter
    def age(self,value):
        self._age = value

if __name__ == '__main__':
    user = User("derek",date(year=1994,month=11,day=11))
    user.age = 23
    print(user._age)   # 23
    print(user.age)    # 24 ,动态计算出来的

 

原型: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)情势

除此以外,在回调函数里也时不时利用这一个函数,对回调弄整驾驭不深,那里不再比如

1.2.__getattr__和__getattribute__的区别

object.__getattr__(self, name) 
找不到attribute的时候,会调用getattr,重返1个值或AttributeError卓殊。 

object.__getattribute__(self, name) 
义务医治被调用,通超过实际例访问属性。假设class中定义了__getattr__(),则__getattr__()不会被调用(除非展现调用或引发AttributeError非常)

 

(1)调用2个不设有的习性

class User:
    def __init__(self,info={}):
        self.info = info

    # def __getattr__(self, item):
    #     return self.info[item]

if __name__ == '__main__':
    user = User(info={"name":"derek","age":24})
    print(user.name)

会报错

图片 1

 

(2)加了__getattr__随后就足以调用了

class User:
    def __init__(self,info={}):
        self.info = info

    #__getattr__是在查找不到属性的时候调用
    def __getattr__(self, item):
        return self.info[item]

if __name__ == '__main__':
    user = User(info={"name":"derek","age":24})
    print(user.name)    #derek

 

 (3)__getattribute__

class User:
    def __init__(self,info={}):
        self.info = info

    #__getattr__是在查找不到属性的时候调用
    def __getattr__(self, item):
        return self.info[item]

    #__getattribute不管属性存不存在,都访问这个
    def __getattribute__(self, item):
        return "zhang_derek"


if __name__ == '__main__':
    user = User(info={"name":"derek","age":24})
    #不管属性存不存在,都走__getattribute__
    print(user.name)    #zhang_derek     #即使属性存在也走__getattribute__
    print(user.test)     #zhang_derek    #不存在的属性也能打印
    print(user.company)   #zhang_derek   #不存在的属性也能打印

 

 

面向对象

  • 编制程序语言:

    • 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>
    
    • 封装:

      • 假使二个类中五个主意必要用到同三个参数,每趟都穿的话,太难为
      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,那样方法的参数重复且调用的时候很麻烦,假设把它们都打包到目的里,直接在目的里调用,这样重复的参数只必要穿1次就能够.
      • 打包步骤

        • 地点的卷入进程不够好,因为即使人家看您的代码,别人不自然精晓调用方法前须要封装数据,可以优化为:
        • 创造对象时会调用构造方法__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中再而三是急需在子类的类名后跟上:(父类类名)
      • 父类--子类
      • 基类--派生类
      • 派生类和父类有同1的法马时,以派生类为主
      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为主
    • Python中用字符串调用函数或方法示例代码,内建函数getattr工厂模式。多承继面试题:

    在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
        • 政工等级:访问后台的地方

先看一下官方文书档案:

1.**3.属性描述符

表明赋值的时候是还是不是int类型

#属性描述符

import numbers

#只要一个类实现了下面三种魔法函数中的一种,这个类就是属性描述符
class IntField:
    def __get__(self, instance, owner):
        return self.value
    def __set__(self, instance, value):
        if not isinstance(value,numbers.Integral):
            raise ValueError("必须为int")
        self.value = value
    def __delete__(self, instance):
        pass

class User:
    age = IntField()

if __name__ == '__main__':
    user = User()
    user.age = 24
    print(user.age)

假设user.age=二四,值是int,能够经常打字与印刷  

万壹user.age='test',传1个字符串,则会报错

图片 2

 

举个栗子:

getattr(object, name[, default])

1.4.__new__和__init__的区别

(1)__new__格局假若不回去对象,不会进行init方法

class User:
    def __new__(cls, *args, **kwargs):
        print("in new")

    def __init__(self,name):
        print("in init")
        self.name = name

# new是用用来控制对象的生成过程,在对象生成之前
# init是用来完善对象的
# 如果new方法不返回对象,则不会调用init函数
if __name__ == '__main__':
    user = User("derek")

运营结果:未有调用init方法

图片 3

 

 (二)再次回到对象就会进行init方法

class User:
    def __new__(cls, *args, **kwargs):
        print("in new")         #in new
        print(cls)              #cls是当前class对象    <class '__main__.User'>
        print(type(cls))        #<class 'type'>
        return super().__new__(cls)   #必须返回class对象,才会调用__init__方法

    def __init__(self,name):
        print("in init")        #in init
        print(self)             #self是class的实例对象      <__main__.User object at 0x00000000021B8780>
        print(type(self))       #<class '__main__.User'>
        self.name = name

# new是用用来控制对象的生成过程,在对象生成之前
# init是用来完善对象的
# 如果new方法不返回对象,则不会调用init函数
if __name__ == '__main__':
    user = User(name="derek")

#总结
# __new__ 用来创建实例,在返回的实例上执行__init__,如果不返回实例那么__init__将不会执行
# __init__ 用来初始化实例,设置属性什么的

 

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.

一.五.自定义元类

(1)前戏:通过传播区别的字符串动态的创立差异的类

def create_class(name):
    if name == 'user':
        class User:
            def __str__(self):
                return "user"
        return User

    elif name == "company":
        class Company:
            def __str__(self):
                return "company"
        return Company

if __name__ == '__main__':
    Myclass = create_class("user")
    my_obj = Myclass()
    print(my_obj)    #user
    print(type(my_obj))     #<class '__main__.create_class.<locals>.User'>

 

(2)用type创建

虽说上边的格局可以创建,但很劳累,上面是type创造类的一个简约实例

# 一个简单type创建类的例子
#type(object_or_name, bases, dict)
#type里面有三个参数,第一个类名,第二个基类名,第三个是属性
User = type("User",(),{"name":"derek"})

my_obj = User()
print(my_obj.name)    #derek

(3)不但能够定义属性,还足以定义方法

def say(self):     #必须加self
    return "i am derek"

User = type("User",(),{"name":"derek","say":say})

my_obj = User()
print(my_obj.name)     #derek
print(my_obj.say())    #i am derek

 

(肆)让type创造的类传承多个基类

def say(self):     #必须加self
    return "i am derek"

class BaseClass:
    def answer(self):
        return "i am baseclass"

#type里面有三个参数,第一个类名,第二个基类名,第三个是属性
User = type("User",(BaseClass,),{"name":"derek","say":say})

if __name__ == '__main__':

    my_obj = User()
    print(my_obj.name)          #d erek
    print(my_obj.say())         # i am derek
    print(my_obj.answer())      # i am baseclass

 

怎么样是元类?

元类正是创立类的类,举例上边的type

在事实上编码中,大家一般不直接用type去创设类,而是用元类的写法,自定义一个元类metaclass去创设

# 把User类创建的过程委托给元类去做,这样代码的分离性比较好

class MetaClass(type):
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls,*args, **kwargs)

class User(metaclass=MetaClass):
    def __init__(self,name):
        self.name = name

    def __str__(self):
        return "test"

if __name__ == '__main__':
    #python中类的实例化过程,会首先寻找metaclass,通过metaclass去创建User类
    my_obj = User(name="derek")
    print(my_obj)    #test

 

这样的话,想想是或不是用途繁多,作者可以把办法名配置到文件中,读取时行使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:Python27python.exe D:/weixin/python_getattr.py
this is number
this is string
this is date

Process finished with exit code 0

德姆o:2个模块辅助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学习交换三群新开,应接加入,一同学习.qq 三群:5632278九四

参考资料:

不前进,不倒退,停止的情况是绝非的.

Python找那么些的getattr()函数详解

壹道前行,与君共勉,

python2.7文档

了解getattr的应该了然,getattr(a, 'b')的效果就和a.b是同等的 那么那么些内建函数有怎么着效能呢,最方便的可相信是行使它来贯彻工厂...

本文由澳门新萄京官方网站发布于www.8455.com,转载请注明出处:Python中用字符串调用函数或方法示例代码,内建

关键词: