我知道装饰器是一个函数,它接受另一个函数并扩展其行为。 在下面的示例中,我之前假设 test() 现在实际上等同于 decorator(test)()。
def decorator(func):
def wrapper(*args, **kwargs):
...
res = func(*args, **kwargs)
...
return res
return wrapper
@decorator
def test():
pass
但是,在装饰器中添加函数属性后,同时运行test()和decorator(test)(),结果是不同的。看起来,在 decorator(test)() 的情况下,装饰器函数确实运行了,因此 num 被重置;当使用 @decorator 时,装饰器函数没有按照我的预期运行?
def decorator(func):
decorator.num = 0
def wrapper(*args, **kwargs):
...
res = func(*args, **kwargs)
...
return res
return wrapper
@decorator
def test():
pass
def test2():
pass
decorator.num = 5
test()
print(decorator.num)
decorator.num = 5
decorator(test2)()
print(decorator.num)
---------------------
5
0
您的困惑源于何时装饰器运行。语法
@decorator
def foo(): ...
相当于
def foo(): ...
foo = decorator(foo)
也就是说,在函数定义之后,立即调用装饰器,并且调用装饰器的结果被赋值回原来的函数名。它仅在定义时调用一次,而不是每个函数调用一次。
班级也是如此。语法
@decorator
class Foo: ...
相当于
class Foo: ...
Foo = decorator(Foo)
先生。 Mayolo,一个与装饰器语法相关的问题:
如果语法
@decorator
class Foo: ...
相当于
class Foo: ...
Foo = decorator(Foo)
以下示例使用装饰器@property:
class A:
def __init__(self, name):
self._name = name
@property
def name(self):
print('Returning value')
return self._name
@name.setter
def name(self, value):
print('Setting value')
self._name = value
可以重写为:
class A:
def __init__(self, name):
self._name = name
def name(self):
print('Returning value')
return self._name
name = property(name)
def name(self, value): # Overrides the above identifier 'name'
print('Setting value')
self._name = value
name = name.setter(name)
这会产生错误,因为第二个方法“name”覆盖了标识符“name”。你能解释一下装饰器@property是如何实现的吗?非常感谢您的回复。