装饰属性:正确的顺序

Cof*_*orm 5 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
Run Code Online (Sandbox Code Playgroud)

Mis*_*agi 3

属性是包装函数的对象(描述符)。装饰哪一件取决于您打算改变哪一件。

  1. 如果你想改变它的作用property 请装饰初始函数。

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

    这也适用于更改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
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果您想更改property is 的内容,请装饰生成的描述符。

    @random_repr  # add a new repr to the descriptor
    @property
    def a(self):
        return 1
    
    Run Code Online (Sandbox Code Playgroud)

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

    @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
    
    Run Code Online (Sandbox Code Playgroud)

大多数情况下,aproperty用于获取函数所表达的某种行为(情况 1)。数据描述符(情况 2)是大多数人不熟悉的实现细节。如有疑问,请装饰该函数 - 这种情况更通用且更容易理解。