CodeWalk

Python 中 descriptors 实现 @property

作者:孤独的心 · 2026-05-30 12:55

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__