• python--reflect


    一、反射
    python 中用字符串的方式操作对象的相关属性,python 中一切皆对象,都可以使用反射
    用eval 有安全隐患,用 反射就很安全
    1.反射对象中的属性和方法
    class A:
        a_class = '反射类静态属性'
        @classmethod
        def func_class(cls):
            return '反射类方法'
        def __init__(self, name):
            self.name = name
            print('%s是对象属性' % (self.name))
        def func(self):
            return '反射对象方法'
    2、getatter   获取
    1. 反射对象中的属性和方法
    a = A('zzy') # zzy是对象属性 实例化的时候会触发init,打印zzy是对象属性
    原版:a.name
    ret = getattr(a, 'name')   #
    print(ret)      # zzy
    原版:a.func()
    ret2 = getattr(a, 'func')
    print(ret2)     #<bound method A.func of <__main__.A object at 0x01B5EBB0>>打印的是函数地址,并没有调用
    ret2()     #加括号就表示调用,打印‘对象方法’
    简洁版
    print(getattr(a, 'name'))      #zzy是对象属性,zzy
    print(getattr(a,'func')())     #反射对象方法
    例二
    2.反射类的静态属性和方法
    #原版:A.func_class()
    print(getattr(A,'func_class')())     #zzy是对象属性
    print(getattr(a,'func_class')())    #反射类方法---->>用对象调用类方法也可以,但是不推荐,
    #原版:A.a_class
    print(getattr(A,'a_class'))    #反射类静态属性
    """
    注释:getattr (对象/类,‘属性/方法’)    属性/方法必须是字符串形式
    getattr 反射方法的时候,要在末尾加(),才能算是调用,否则打印的只是函数地址
    """
    要反射的函数有参数怎么办?
    # print(time.strftime('%Y-%m-%d %H:%M:S'))
    # print(getattr(time,'strftime')('%Y-%m-%d %H:%M:S'))
    3、hasattr  有
    #判断需要反射的对象是否存在,和getattr是夫妻档,判断存在的时候,才会执行getattr
    if hasattr(a,'name'):
        print(getattr(a,'name'))         #   zzy是对象属性   zzy
    4、setattr  设置修改变量
    class A:
        pass
    a = A()
    setattr(a,'name','nezha')      #在对象a中新建属性name属性,并且赋值'nezha'
    setattr(A,'name','alex')        #在A类中新建静态属性name属性,并且赋值'alex'
    print(A.name)   #alex
    print(a.name)   #'nezha
    setattr
    5、delattr 删除一个变量
    delattr(a,'name')     #删除对象a中新建属性name属性
    print(a.name)       #删除后打印会报错
    delattr(A,'name')   #删除在A类中新建静态属性name属性
    print(a.name)     #删除后打印会报错
    delattr
    6、进阶使用1,涉及用户交互
    变量名=input('请输入:')
    print(getattr(a,变量名))   #zzy
    练习,需求:用户输入time 和 asctime打印出time.time/asctime
    import time
    t=input('请输入:')   #输入time / asctime
    print(getattr(time,t)())    #  因为输入的是time / asctime,而
    #注释:说明内置函数也是可以反射的
    练习
    7、进阶使用2,涉及其他导入模块的反射
    (1)反射其他模块
    import sys
    import model
    b=model.B('zzy')
    #反射模块的类属性
    原版:print(b.name)
    print(getattr(b,'name'))   #zzy
    #反射模块类方法
    原版: b.func1()
    print(getattr(b,'func1')())    #你好
    (2)反射模块中变量
    import model
    #原版:model.soga       #   model模块 中有soga=input('请输入:')

    print(getattr(model,'soga')) #打印你输入的内容 #反射模块中的函数
    # 原版model.foo()
    print(getattr(model,'foo')('zxc')) #zxc 函数中有参数的话,就可以在括号里('zxc')传进去
    (3)反射模块中的函数
    # 原版model.foo()
    # print(getattr(model,'foo')('zxc'))    #zxc  函数中有参数的话,就可以在括号里('zxc')传进去
    8、进阶3:反射自己模块
    (1)导入自己模块的变量
    msg=1+2print(getattr(sys.modules['__main__'],'msg')
    (2)导入自己模块的函数
    def foo (a):
        return a
    print(getattr(sys.modules[__name__],'foo')('zxc'))        #zxc
    (3)反射自己模块的类
    class C:
        a_class = '反射模块类静态属性'
        @classmethod
        def func_class(cls):
            return '反射模块类方法'
        def __init__(self, name):
            self.name = name
        @property
        def func_c(self):
            return '反射模块对象方法'
        @staticmethod
        def func():
            return '我是一个普通的函数'
    类函数
    import sys
    c=C('ZZY')
    print(getattr(sys.modules['__main__'],'C'))     #<class '__main__.C'>  类的函数地址
    print(getattr(sys.modules['__main__'],'c'))     #<__main__.C object at 0x01B77210>   对象的函数地址
    print(getattr(sys.modules['__main__'],'c').name)     #ZZY    对象.name  就可以调用自己模块中类的方法名了
    print(getattr(sys.modules['__main__'],'C').func_class())    #反射模块类方法
    print(getattr(sys.modules['__main__'],'c').func_c)     #反射模块对象方法
    print(getattr(sys.modules['__main__'],'C').func())    #我是一个普通的函数
    #注释:sys.modules['__main__']找到当前运行的模块
    #最好用sys.modules['__name__'],因为__name__ 永远获取的是__name__所在的模块
    反射
    9、比较区别
    先在一个reflect.py文件中打印
    print(sys.modules[__name__])
    print(sys.modules['__main__'])
    再在另一个model.py文件在中执行下列
    import reflect      #导入reflect模块了,就会执行reflect模块中的程序
    
    #reflect  中运行了print(sys.modules[__name__])
    就会打印:<module 'reflect' from 'D:\Users\ZhaoYun Zhu\PycharmProjects\reflect.py'>
    
    # reflect  中运行了print(sys.modules[__main__])
    就会打印:<module '__main__' from 'D:/Users/ZhaoYun Zhu/PycharmProjects//model.py'>
    
    # 总结:sys.modules['__main__']找到当前运行的模块
    # 最好用sys.modules['__name__'],因为__name__ 永远获取的是__name__所在的模块
  • 相关阅读:
    API文档大集合
    jenkins 构建 job 并获取其状态的实现
    jenkins 插件乱码处理与文件上传
    更优雅的配置:docker/运维/业务中的环境变量
    部署仓库中 nginx 下游依赖配置改进
    dotnet core 在 MIPS64 下的移值进度:EA 版本已经发布
    tmux 编译安装过程
    各数据源的时间/日期的提取能力对比
    关于若干性能指标的阐述
    为缓存、外部接口调用添加超时处理
  • 原文地址:https://www.cnblogs.com/zzy-9318/p/8379608.html
Copyright © 2020-2023  润新知