装饰属性:正确的顺序

时间:2019-04-25 11:07:51

标签: python

是否存在装饰类属性的首选方法? 如我所见,您可以用另一个属性来装饰属性本身,也可以装饰基础方法,然后在其上应用@property
两种方法都需要考虑吗?

def decorate_property(prop):
    @property
    def inner(instance):
        return prop.__get__(instance) + 1
    return inner

def decorate_func(func):
    def inner(instance):
        return func(instance) +1
    return inner

class A:

    x = 1

    @decorate_property
    @property
    def f(self):
        return self.x

    @property
    @decorate_func
    def g(self):
        return self.x

a = A()
print(a.f) # 2
print(a.g) # 2

1 个答案:

答案 0 :(得分:2)

属性是包装函数的对象(descriptors)。装饰哪一个取决于您打算更改哪一个。

  1. 如果要更改property 的功能,请修饰初始功能。

    @property
    @plus_one  # add one to the result of the function
    def a(self):
        return self._a
    

    这也适用于更改setterdeleter

    @property
    @plus_one  # add one to the result of the function
    def a(self):
        return self._a
    
    @a.setter
    @minus_one  # remove one from the input of the function
    def a(self, value):
        self._a = value
    
  2. 如果要更改property 是什么,请修饰生成的描述符。

    @random_repr  # add a new repr to the descriptor
    @property
    def a(self):
        return 1
    

    请注意,定义setterdeleter会创建一个 new 描述符。您需要装饰最后创建的描述符。

    @property
    def a(self):
        return self._a
    
    @random_repr  # add a new repr to the final descriptor
    @a.setter
    def a(self, value):
        self._a = value
    

在大多数情况下,property用于获得由函数表示的特定行为(情况1)。数据描述符(案例2)是大多数人不熟悉的实现细节。如有疑问,请装饰函数-这种情况更为通用且更易于理解。