(11)python反射,类的反射
【1】基本方法
反射
hasattr(obj,name_str),判断一个对象 obj里是否有对应的 name_str字符串的方法
getattr(obj,name_str),获取对象 Obj 里对应 name_str字符串方法的内存地址
setattr(obj,name_str,new_value) ,设置对象加一个新的属性,比如:obj.name_str = 'new_value'
delattr(obj,name_str),删除对象 Obj.name_str
【2】基本实践演示
【2.1】类实例内外方法的映射:类中的方法=》反射=》外部函数
class dog(object): def __init__(self,name): self.name = name def eat(self): print("{} is eating...".format(self.name)) d = dog("wangcai") choice = "eat" print(hasattr(d,choice)) # 判断d实例对象所属类 中是否有 choice变量值的方法(即eat方法) print(getattr(d,choice)) # 反向通过变量值,找到内存中存放该变量值对应方法的内存地址(即eat方法存储所对应的内存地址) a = getattr(d,choice) # 这样就 映射出来方法,然后调用了 a() # 或者这样调用也可以 getattr(d,choice)()
输出结果:
True <bound method dog.eat of <__main__.dog object at 0x012A1E68>> wangcai is eating...
【2.2】类实例内外方法的映射:外部方法=》反射=》类实例方法
把外部的 bulk 函数,反射成了 类中不存在的的 talk 方法,
通过反射 外部 bulk 函数 = 实例对象的 talk 方法
class dog(object): def __init__(self,name): self.name = name def eat(self): print("{} is eating...".format(self.name)) d = dog("wangcai") new_choice = input("new var>>:") # 输入 talk if hasattr(d,new_choice): func = getattr(d,new_choice) #类中的方法=》反射=》外部函数
func("张三丰")
else: def bulk(self): print("{} 正在大声喊叫".format(self.name)) setattr(d,new_choice,bulk) # 把常规函数,反射成类实例可以调用的方法 d.talk(d) # 外部方法=》反射=》类实例方法;这里为什么写 talk 因为我输入的是 talk
结果:
new var>>:talk
wangcai 正在大声喊叫
【2.3】类实例内外变量的相互映射
class dog(object): def __init__(self,name): self.name = name def eat(self): print("{} is eating...".format(self.name)) d = dog("wangcai") new_choice = input("input your property:") if hasattr(d,new_choice): func = getattr(d,new_choice) # 类实例内部变量获取到地址,即 new_property = d.name print(new_property) else: setattr(d,new_choice,'age在类中没有定义,我是反射出来的新变量~{}'.format(new_choice)) print(getattr(d,new_choice)) # print(d.age) 也可以这样,但这就写死了,必须是输入的 age
结果1:类实例 存在变量 new_choice 值的属性时(即 if 中的代码)
input your property:name
wangcai
结果2:类实例 不存在变量 new_choice 值的属性时(即 else 中的代码)
input your property:age
age在类中没有定义,我是反射出来的新变量~age
【2.4】反射=》删除类属性
class dog(object): def __init__(self,name): self.name = name def eat(self): print("{} is eating...".format(self.name)) d = dog("wangcai") new_choice = input("input your property:") if hasattr(d,new_choice): func = getattr(d,new_choice) # 类实例内部变量获取到地址,即 new_property = d.name delattr(d,new_choice) # 删除类属性,如果输入的是类方法名,这个无法删除,会报错,如果有类属性和类方法同名也没关系,因为先执行__init__的原因,先获取到的是属性