反射(自省)

# 反射(也称为自省)

# 反射的概念:指程序可以访问、检测和修改它本身状态或行为的一种能力

# 四个可以实现反射的函数
# 下列方法适用于类和对象
# hasattr(object, name) 第一个参数传对象,第二个参数传一个字符串
# 判断object中有没有name属性
class A:
    a = 'aaa'

    def __init__(self, name, addr):
        self.name = name
        self.addr = addr

    def test(self):
        print('test')


a = A('张三', '高新区')

print(hasattr(a, 'addr'))  # true 对象中有addr这个数据属性
print(hasattr(a, 'test'))  # true 对象中有test这个函数属性
print(a.__dict__)  # 只显示对象的数据属性,不显示函数属性

# getattr(object, name, [default]) 第一个参数传对象,第二个参数传一个字符串
# 获取object中name属性的值,没有相应属性时会报错,如果设置了default,则不会报错,会返回设置的default
print(getattr(a, 'addr'))  # 高新区
print(getattr(a, 'test'))  # <bound method A.test of <__main__.A object at 0x03D37790>>
print(getattr(a, 'test111', '这里设置了default'))  # 这里设置了default

# setattr(x, y, v) 第一个参数传对象,第二个参数传要设置的key,第三个参数传要设置的value
# 新增或修改object中y属性的值
print(setattr(a, 'tel', '18919901111'))  # 新增
print(setattr(a, 'addr', '不是高新区'))  # 修改
print(a.__dict__)  # {'name': '张三', 'addr': '不是高新区', 'tel': '18919901111'}

# delattr(o, name) 第一个参数传对象,第二个参数为属性名的字符串
# 删除 object中name属性
print(delattr(a, 'tel'))
print(delattr(a, 'addr'))
print(a.__dict__)  # {'name': '张三'}


# 反射的应用场景:程序员A编写了一个类,但是没有完成去度假,程序员B使用A写的类,可以使用反射继续完成自己的代码
# 等A回来后继续完成类的定义并且去实现B想要的功能。这种方式也叫做可插拔设计

class FtpClient:  # 这个类是A写的,但是没有完成
    def __init__(self, addr):
        print('正在连接服务器', addr)
        self.addr = addr


f1 = FtpClient('192.168.8.8')  # B使用A的类实例化对象
if hasattr(f1, 'get'):  # 判断f1对象是否有get函数属性
    func_get = getattr(f1, 'get')  # 如果有,则获取该函数属性的内存地址
    func_get()  # 执行该函数
else:  # 如果没有,再进行处理其它的逻辑
    print('不存在get方法')
    print('继续处理其它逻辑')
    
# 当A回来后编写了get方法,此时无需对B的代码进行修改

猜你喜欢

转载自www.cnblogs.com/dangrui0725/p/9461852.html