python08-反射 & 面向对象(一)

2019-12-04 19:00栏目:bob体育平台
TAG:

getattr(卡塔尔(英语:State of Qatar)那么些艺术最珍视的机能是促成反射机制。也便是说能够通过字符串获取格局实例。  传入不一致的字符串,调用的法子差异样。

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. 经过字符串的款式去模块中搜索制定的积极分子(属性、函数卡塔尔(英语:State of Qatar),并选用
# 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)
  • 地方的函数也便是调用了2个函数

    • __import__(卡塔尔(قطر‎:通过字符串导入模块对象
    • getattr(module,attr卡塔尔(قطر‎:获取模块里的成分
  • 实际上getattr(卡塔尔国函数才叫反射,通过字符串的款式在模块中搜索对应的要素,借使成分不设有,则报错.

  • 能够透过给getattr(module,arrtib,def卡塔尔(قطر‎设置暗许值,幸免报错

  • 反射函数

    • getattr(卡塔尔(英语:State of Qatar):获取属性
    • delattr(卡塔尔国:删除属性
    • hasattr(卡塔尔国:决断实行是不是存在
    • setattr(卡塔尔(英语:State of Qatar):增加或涂改属性
  • python中,一切皆对象,通过反射,根据字符串去对象中(模块,类卡塔尔(قطر‎获取成分

  • 扩展

    • 通过__import__(卡塔尔(英语:State of Qatar)导入的模块假诺存在的门路为:libmodulesmoudle.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本质都以这么些道理

 

面向对象

  • 编制程序语言:

    • 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,那样方法的参数重复且调用的时候很麻烦,假诺把它们都卷入到目的里,直接在对象里调用,那样重复的参数只须要穿叁次就能够.
      • 打包步骤

        • 地点的包装进程相当不足好,因为只要外人看你的代码,外人不必然知道调用方法前要求封装数据,能够优化为:
        • 创立对象时会调用构造方法__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
        • 事情品级:访谈后台之处

举个栗子:

pyMethod类下定义了四个主意,getattr(pyMethod(卡塔尔(英语:State of Qatar),'out%s'%str卡塔尔(卡塔尔(英语:State of Qatar)   传入的办法名不一样,调用区别的点子。些处方法名称为字符串。

那样的话,思考是还是不是用处非常多,作者能够把艺术名配置到文件中,读取时利用getattr动态去调用。

版权声明:本文由bob体育app发布于bob体育平台,转载请注明出处:python08-反射 & 面向对象(一)