有没有装饰类属性的首选方法?如我所见,您可以用另一个属性来装饰属性本身,也可以装饰基础方法,然后@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)
属性是包装函数的对象(描述符)。装饰哪一件取决于您打算改变哪一件。
如果你想改变它的作用property
,请装饰初始函数。
@property
@plus_one # add one to the result of the function
def a(self):
return self._a
Run Code Online (Sandbox Code Playgroud)
这也适用于更改setter
和deleter
。
@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)如果您想更改property
is 的内容,请装饰生成的描述符。
@random_repr # add a new repr to the descriptor
@property
def a(self):
return 1
Run Code Online (Sandbox Code Playgroud)
请注意,定义setter
并deleter
创建一个新的描述符。您需要装饰最后创建的描述符。
@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)是大多数人不熟悉的实现细节。如有疑问,请装饰该函数 - 这种情况更通用且更容易理解。