目录
反射
概述:
- 运行时,区别于编译时,指的是程序被加载到内存中执行的时候
- 反射【reflection】,指的是运行时获取类定义的信息
- 一个对象能够在运行时,像照镜子一样,反射出其类型信息
- 简单说,在Python中,能够通过一个对象,找出其type、class、attribute或method的能力,称其反射或者自省
- 具有反射能力的函数有:type()、isinstance()、callable()、dir()、getattr()
反射相关函数和方法
需求:有个Poine类,查看它实例的属性,并修改它。动态为实例增加属性
class Point: def __init__(self,x,y): self.x = x self.y = y def __str__(self): return "Point({},{})".format(self.x,self.y) def show(self): print(self.x,self.y) p = Point(4,5) print(p) # Point(4,5) print(p.__dict__) # {'x': 4, 'y': 5} p.__dict__["y"] = 16 print(p.__dict__) # {'x': 4, 'y': 16} p.z = 10 print(p.__dict__) # {'x': 4, 'y': 16, 'z': 10} print(sorted(dir(p))) # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'show', 'x', 'y', 'z'] print(sorted(p.__dir__())) # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'show', 'x', 'y', 'z']
上例通过属性字典【__dict__】来访问对象的属性,本质上也是利用的反射的能力,但是上面的例子中,访问的方式不优雅,Python提供了内置的函数
内建函数 意义 getattr(object,name[,default]) 通过name返回object的属性值。当属性不存在,将使用default返回,如果没有default,则抛出AttributeErrot。name必须为字符串 setattr(object,name,value) object的属性存在,则覆盖,不存在,新增 hasattr(object,name) 判断对象是否有这个名字属性,name必须为
字符串
用上面的方法来修改上例的代码class Point: def __init__(self,x,y): self.x = x self.y = y def __str__(self): return "Point({},{})".format(self.x,self.y) def show(self): print(self.x,self.y) a = Point(4,5) b = Point(10,10) print(repr(a),repr(b)) # <__main__.Point object at 0x017B9250> <__main__.Point object at 0x017B9CD0> print(a.__dict__) # {'x': 4, 'y': 5} setattr(a,"y",16) setattr(a,"z",100) print(getattr(a,"__dict__")) # {'x': 4, 'y': 16, 'z': 100} # 动态调用方法 if hasattr(a,"show"): getattr(a,"show")() # 4 16 # 动态增加方法 # 为类增加方法 if not hasattr(Point,"add"): setattr(Point,"add",la