python-反射


我们常常会遇到这样的需求:需要执行对象里的某个方法,或需要调用对象中的某个变量,但是由于种种原因我们无法确定这个方法或变量是否存在,这是我们需要用一个特殊的方法或机制要访问和操作这个未知的方法或变量,这中机制就称之为反射。
hasattr()、getattr()、setattr()函数
class A(object):
    name = 'python'
    def __init__(self):
        setattr(self.__class__, 'func_init', self.func)

    def func(self):
        return 'Hello world:func'
    @staticmethod
    def funcmethod():
        return 'Hello world:funcmethod'

"""
hasattr(object, name)
判断object对象中是否存在name属性,属性包含变量和方法;有则返回True,没有则返回False;
name为string类型
"""
print('hasattr==>')
print(hasattr(A, 'name'))   #判断变量
print(hasattr(A, 'func'))   #判断方法


"""
getattr(object, name[, default])
获取object对象的name属性的值,如果存在则返回属性值,不存在需要给定值,否则报错
属性为方法时:1实例类,2加括号调方法
"""
print('getattr==>')
print(getattr(A, 'name'))           #返回已定义属性值,再给定值也是无效
print(getattr(A, 'age', 20))        #返回未定义属性需要给定值,否则报错;不可在下次直接使用
print(getattr(A, 'func'))           #返回函数对象
print(getattr(A(), 'func')())       #返回函数的返回值
print(getattr(A, 'funcmethod')())   #返回@staticmethod函数的返回值


"""
setattr(object, name, value)  object为对象不是单纯的字符串
给object对象的name属性赋值,存在则修改,不存在则创建(可在同一个实例中直接使用)
"""
print('setattr==> name:{}'.format(getattr(A, 'name')))
setattr(A, 'name','shuzf')   #修改变量值
setattr(A, 'age',30)        #创建变量并赋值
print(getattr(A, 'name'))   #返回已定义属性值
print(getattr(A, 'age'))    #返回未定义属性
#value为该对象方法时:获取name属性值,即获取方法;外部赋值方法为静态方法,内部赋值不需要直接self.func
setattr(A,'funcmethod_main',A.funcmethod) #创建变量并赋值方法
print(getattr(A,'funcmethod_main')())     #返回未定义属性值,外部赋值,值为方法
print(getattr(A,'func_init')())           #返回未定义属性值,内部赋值,值为方法
#对上面演示:对于已实例的对象,则不需要考虑是否是静态方法
import sys
class A:
    def __init__(self, str):
        self.name = str  # name不为该类的属性
        setattr(self.__class__, self.name, self.test)

    def test(self):
        return sys._getframe().f_code.co_name


if __name__ == '__main__':
    a = A("shuzf")

    print(a.shuzf)
    print(a.shuzf())
    print(getattr(a, 'shuzf'))
    print(getattr(a, 'shuzf')())

    setattr(a, 'func', a.test)
    print(a.func)
    print(a.func())
    print(getattr(a, 'func'))
    print(getattr(a, 'func')())



#对上面演示:对于类内部使用三函数,类名、self都是可以的;创建多个实例类时
#A.name创建的属性可以多个实例相互使用,说明地址没有回收
#setattr创建的属性只能同一个实例使用
class A():
    def __init__(self):
        setattr(self.__class__, 'func_class', self.func)

    def func(self):
        print(hasattr(self, 'name'))  # 判断变量
        A.name = 'python'  #创建变量
        #setattr(self, 'name','python')# 创建变量
        print(getattr(self, 'name'))  # 获取变量
        return 'Hello world:func'

if __name__ == '__main__':
    print(getattr(A(), 'func')())
    print(getattr(A(), 'func')())
原文地址:https://www.cnblogs.com/shuzf/p/14654709.html