反射
- 通过字符串映射或修改程序运行时的状态,属性,方法.
- 有以下四种方法:
- getattr(object, name, default = None)
- hasattr(object, name)
- setattr(x,y,v)
- delattr(x,y)
-
#!/usr/bin/python# -*- coding: utf-8 -*-def bulk(self): print("%s is yelling...." % self.name)class Dog(object): def __init__(self, name): self.name = name def eat(self, food): print("%s is eating %s...", self.name, food) def walk(self): print("%s is walking...", self.name)d = Dog("NHY")choice = input(">>:").strip() # 用户输入"吃", 就调用eat()方法; 用户输入"走", 就调用walk()方法# print(hasattr(d, choice)) # 判断用户输入是否存在于实例d中. 若用户输入eat, 会返回True; 若用户输入talk,会返回False."""但是即使eat返回True,也不能直接调用 d.choice, 因为choice是不存在的, 必须把用户输入的eat调出来, 需要用到getattr()方法"""# print(getattr(d, choice)) # 若用户输入eat, 就返回一个内存地址(返回内存地址之后, 加括号就能调用相应方法了); 若用户输入talk,因为不存在, 会返回False.# getattr(d, choice)("包子") # 若用户输入eat,此行代码相当于调用 eat()方法. 若不需要传参数, 直接getattr(d, choice)()即可."""反射步骤总结: 1. hasattr(obj, name_str) 判断是否存在某字符串的方法映射 2. getattr(obj, name_str) 若该映射存在, 获取该映射对应方法的内存地址 3a. getattr(obj, name_str)() 如果是一个方法, 获取内存地址之后, 调用相关方法 3b. setattr(ojb, 'y', v) 如果是一个属性, 重新设置该属性的值. is equivalent to obj.y = v. 4. delattr() 删除一个属性"""# 传递一个动态方法if hasattr(d, choice): # getattr(d, choice)() # 这样直接调用eat()方法, 有时还需要传参数,可以用下面的方法 func = getattr(d, choice) func("馒头")else: setattr(d, choice, bulk) # 传递一个动态方法. 即不存在的映射, 可以添加. 但是前提相关方法必须已经存在. setattr(d, choice, None) # 传递一个动态属性d.talk(d) # 用户输入talk, 所以要调用talk(),而不是bulk(). bulk相当于一个变量名, 此处因用户输入了talk,用talk来代替. 相当于d.talk = bulk, 所以d.talk()就是调用bulk()方法."""上面写死了. 因为不确定用户choice会输入什么, 所以应该用一个变量来接收getattr()的值"""if hasattr(d, choice): # getattr(d, choice)() # 这样直接调用eat()方法, 有时还需要传参数,可以用下面的方法 func = getattr(d, choice) func("馒头")else: setattr(d, choice, bulk) # 传递一个动态方法. 即不存在的映射, 可以添加. 但是前提相关方法必须已经存在. setattr(d, choice, None) # 传递一个动态属性 func = getattr(d, choice) func(d) # 这样不论用户choice输入的是什么都可以直接调用func(d)来执行了.不用写死成d.talk().# 传递一个动态属性, 或给已有属性重新赋值if hasattr(d, choice): attr = getattr(d, choice) setattr(d, choice, "RGH") # 更改已有属性值. 在choice里填name, 改的就是name的值.else: setattr(d, choice, None) # 传递一个动态属性. None是这个动态属性的默认值.可以是None,也可以是其它值,如2233等. # setattr(d, choice, 22) print(getattr(d, choice))print(d.name)# 删除一个属性if hasattr(d, choice): delattr(d, choice)