python @property装饰器实现原理

发布时间 2023-08-22 11:56:37作者: 顺其自然,道法自然

@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

通过单步跟踪函数的执行过程, 可以搞明白函数的实现原理. 参考代码中注释.