Python 中 descriptors 实现 @property
Python 中 @property 装饰器的底层实现原理是什么?请用描述符(Descriptor)手动实现一个类似 @property 的功能。
回答
孤独的心
@property 底层是数据描述符,实现了 __get__、__set__、__delete__。
class MyProperty:
def __init__(self, fget=None, fset=None, fdel=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
def __set_name__(self, owner, name):
self.attr_name = name
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError('unreadable attribute')
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError('cant set attribute')
self.fset(obj, value)
def setter(self, fset):
return type(self)(self.fget, fset, self.fdel)
class Circle:
def __init__(self, r):
self._r = r
@MyProperty
def radius(self):
return self._r
@radius.setter
def radius(self, value):
if value <= 0:
raise ValueError('Radius must be positive')
self._r = value
当访问 obj.radius 时,Python 发现类中有名为 radius 的数据描述符,调用其 __get__。