python @property装饰器实现原理
@property装饰器可以使一个对象的方法变成属性访问, 比较方便, 那么它是如何实现的呢? 下面是一个自己动手实现的例子:
class MyProperty:
def __init__(self, fget=None, fset=None):
self.fget = fget
self.fset = fset
def __get__(self, instance, owner):
if instance is None:
return self
if self.fget is None:
raise AttributeError("unreadable attribute")
return self.fget(instance)
def __set__(self, instance, value):
if self.fset is None:
raise AttributeError("can't set attribute")
self.fset(instance, value)
def getter(self, fget):
return type(self)(fget, self.fset)
def setter(self, fset):
return type(self)(self.fget, fset)
class MyClass:
def __init__(self):
self._x = 88
@MyProperty
def x(self): # 运行到此处, 会生成一个名字为x, 类型为MyProperty的对象, 对象的fget为MyClass.x函数
return self._x
@x.setter
def x(self, value): # 此处会调用x对象的setter方法, 重新生成一个x对象, 此时x对象就同时拥有fget和fset方法了
self._x = value
a = MyClass()
a.x = 99 # 会调用MyProperty对象的__set__方法, 并把a作为instance传递进去
print(a.x) # 99
通过单步跟踪函数的执行过程, 可以搞明白函数的实现原理. 参考代码中注释.