我写了一个简单的装饰:
from functools import wraps
import random
def my_dec(f):
lst = list()
@wraps(f)
def wrapper(*args):
lst.append(random.randint(0, 9))
print(lst)
return f(*args)
return wrapper
@my_dec
def foo():
print("foo called")
现在,如果我多次调用foo
,则lst
不会被刷新。相反,它会随着时间的推移而积累。因此,foo
的多个调用返回如下输出:
foo()
> [4]
> foo called
foo()
> [4, 9]
> foo called
foo()
> [4, 9, 1]
> foo called
...
为什么?我以为decorator
只是my_dec(foo)
的语法糖?!我假设每次对my_dec
的调用都会刷新lst
。你知道吗
你说得对。。。装潢师只是一个语法糖。具体来说:
与以下内容完全相同:
让我们更离奇一点,用另一种方式重写它,大体上相当于
希望这样写出来,你可以看到,如果我多次调用
foo
,我不是在调用decorator
。decorator
只被调用一次(以帮助创建foo
)。你知道吗现在在您的示例中,您的decorator在被调用时立即创建一个列表:
返回的函数
wrapper
被分配给您的foo
,因此当您调用foo
时,您调用的是wrapper
。请注意,wrapper
中没有重置lst
的代码,只有向lst
添加更多元素的代码,因此这里没有任何内容指示lst
应该在调用之间“刷新”。你知道吗1(取决于decorator所做的工作,您可能会看到函数的
__name__
属性存在一些差异,但在其他情况下是相同的…还要注意,每次调用decorator时都有一个
lst
。如果我们喜欢的话,我们可以疯狂地用这个来装饰foo
两次:或者我们可以装饰多个功能:
当我们调用
foo
和bar
时,我们会看到它们各自积累了自己的(不同的)随机数列表。换句话说,每当你的装饰器被应用到某个东西上时,就会创建一个新的列表,并且每次调用“某物”时,列表就会增长。你知道吗相关问题 更多 >
编程相关推荐