zoukankan      html  css  js  c++  java
  • Python面向对象之反射

    一、反射的基本概念

    反射:可以用字符串的方式去访问对象的属性,调用对象的方法(但是不能去访问方法),Python中一切皆对象,都可以使用反射。

    反射有四种方法:

    hasattr(obj, str) #判断一个对象是否有str属性或者string方法,有就返回True,没有就返回False
    
    getattr(obj, str) #获取对象的属性或者方法,如果存在则打印出来,getattr和hasattr配套使用
    #注意:如果返回的是对象的方法,那么返回的是对象的内存地址,如果需要运行这个方法,可以在后面添加一对()
    
    setattr(obj, str, value) #把obj中的str成员设置成value,注意,这里的value可以是值,也可以是函数或者方法
    
    delattr(obj,str) #把obj中的str成员删除掉
    

    注意:以上操作都是在内存中进行的,并不会影响你的源代码

    二、反射示例

    示例1:

    class Foo:
        def __init__(self):
            self.name = 'egon'
            self.age = 51
        def func(self):
            print("hello")
    
    egg = Foo()
    setattr(egg, 'gender', 'male')
    print(egg.gender)
    print(egg.__dict__)
    
    
    def show_name(self):
        print(self.name + 'sb')
    setattr(egg, 'show_name', show_name)
    egg.show_name(egg)
    show_name(egg)
    
    delattr(egg, 'name')
    print(egg.__dict__)
    
    # 打印结果:
    male
    {'name': 'egon', 'age': 51, 'gender': 'male'}
    egonsb
    egonsb
    {'age': 51, 'gender': 'male', 'show_name': <function show_name at 0x101fabe18>}
    

    示例2:

    # 反射示例2
    class Foo:
        pass
    
    f = Foo()
    
    print(hasattr(f, 'chi'))  # False
    
    setattr(f, 'chi', '123')
    print(f.chi)  # 123
    print(f.__dict__)  # {'chi': '123'}
    
    setattr(f, 'chi', lambda x: x + 1)
    print(f.chi(3))  # 4
    print(f.chi)  # 注意:此时的chi既不是静态方法也不是实例方法,更不是类方法,就相当于你在类中写了个 self.chi = lambda 是一样的
    print(f.__dict__)  # {'chi': <function <lambda> at 0x101eabe18>}
    
    delattr(f, 'chi')
    print(hasattr(f, 'chi'))  # False
    
    # 打印结果:
    False
    123
    {'chi': '123'}
    4
    <function <lambda> at 0x101eabe18>
    {'chi': <function <lambda> at 0x101eabe18>}
    False
    
    

    三、反射的应用

    1.对象应用反射

     class Foo:
     2     def __init__(self):
     3         self.name = 'egon'
     4         self.age = 51
     5     def func(self):
     6         print('hello')
     7 egg = Foo()
     8 print(hasattr(egg,'name'))  #先判断name在egg里面存在不存在
     9 print(getattr(egg,'name')) #如果为True它才去得到
    10 print(hasattr(egg,'func'))
    11 print(getattr(egg,'func'))  #得到的是地址
    12 # getattr(egg,'func')()  #在这里加括号才能得到,因为func是方法
    13 if hasattr(egg,'func'):
    14     getattr(egg,'func')()
    15 else:
    16     print('没找到')
    

    2.类应用反射

     1 class Foo:
     2     f = 123
     3     @classmethod
     4     def class_method_dome(cls):
     5         print('class_method_dome')
     6 
     7     @staticmethod
     8     def static_method_dome():
     9         print('static_method_dome')
    10 print(hasattr(Foo,'class_method_dome'))
    11 method = getattr(Foo,'class_method_dome')
    12 method()
    13 print('------------')
    14 print(hasattr(Foo,'static_method_dome'))
    15 method1 = getattr(Foo,'static_method_dome')
    16 method1()
    

    3.模块应用反射

    模块的应用又分为导入其他模块反射和在本模块中反射

    • 到入其他模块反射
     # 1.导入其他模块引用
    2 import mymodule
    3 print(hasattr(mymodule,'test'))
    4 getattr(mymodule,'test')()
    5 
    6 # # 这里的getattr(mymodule,'test')()这一句相当于
    7 # p = getattr(mymodule,'test')
    8 # p()
    
    • 在本模块中应用反射
    1 # 2.在本模块中应用反射
    2 def demo1():
    3     print('wwww')
    4 import sys
    5 # print(sys.modules)
    6 module_obj = sys.modules[__name__]  #相当于'__main__'
    7 print(module_obj)
    8 print(hasattr(module_obj,'demo1'))
    9 getattr(module_obj,'demo1')()
    

    导入自己的模块的一个简单小例子:

     1 # 举例
     2 def 注册():
     3     print('regiester')
     4 def 登录():
     5     print('login')
     6 def 购物():
     7     pass
     8 print('注册,登录,购物')
     9 ret = input('请输入你要做的操作:')
    10 import sys
    11 my_module = sys.modules[__name__]  #利用sys模块导入一个自己的模块
    12 if hasattr(my_module,ret):
    13     getattr(my_module,ret)()
    

    4.其他

    db.mysql

    class MySQlHelper(object):
        print('MySQlHelper1111111')
        def fetchone(self):
            print('你好')
    

    db.pool

    class PoolHelper(object):
        print('PoolHelper')
    

    settings.py

    DB_PATH = 'db.mysql.MySQlHelper'
    
    #吧字符串切割
    module_name,cls_name = DB_PATH.rsplit('.',maxsplit=1)
    # print(module_name,cls_name)  #db.mysql    MySQlHelper
    #导入模块
    # from db.mysql import MySQlHelper
    import importlib
    moudel_obj = importlib.import_module(module_name)
    print(moudel_obj,type(moudel_obj))
    #导入模块中的类
    cls = getattr(moudel_obj,cls_name)
    print(cls)
    #对类进行实例化
    obj = cls()
    obj.fetchone()
    # getattr()
    
  • 相关阅读:
    aircrack-ng 多网卡启动后环境清理
    Docker create image
    预加载(学习一)
    activity+fragment多次切换出现页面空白问题
    万能的Volley
    关于下拉刷新你是否真的非常理解还是只会搬砖?附 Android 实例子源代码文件下载地址380个合集
    如何将Java源代码文件的编码从GBK转为UTF-8?
    如何操作笔记本显得逼格很高?
    跑马灯源代码
    关于java、Android中Math的一些用法
  • 原文地址:https://www.cnblogs.com/russellyoung/p/python-mian-xiang-dui-xiang-zhi-fan-she.html
Copyright © 2011-2022 走看看