gpt4 book ai didi

python - 一个函数有两个装饰器,后一个函数没有按预期工作?

转载 作者:太空宇宙 更新时间:2023-11-03 15:51:09 24 4
gpt4 key购买 nike

我在一个函数上有两个装饰器。每个装饰器都会向函数添加一个属性,但第一个装饰器的属性在启动后不会传递给函数。

为什么下面的代码中f3.calls仍为0?

def memorize(fn):
result_list3 = {}

@wraps(fn)
def wrapper(n):
wrapper.calls2 += 1
print("memorize calls2", wrapper.calls2)
found = result_list3.get(n)
if found is not None:
result = found
else:
result = fn(n)
result_list3.update({n: result})
# print(result_list3)
return result

wrapper.calls2 = 0
return wrapper


def countt(fn):
@wraps(fn)
def wrapper(n):
wrapper.calls += 1
print("countt calls", wrapper.calls)
result = fn(n)
return result

wrapper.calls = 0
return wrapper


@memorize
@countt
def f3(n):
if n < 3:
return n
else:
result = f3(n - 1) + 2 * f3(n - 2) + 3 * f3(n - 3)
return result


if __name__ == '__main__':
print(f3(10))
print(f3.calls) # 0
print(f3.calls2) # 25

这是日志:

memorize calls2 1
countt calls 1
memorize calls2 2
countt calls 2
memorize calls2 3
countt calls 3
memorize calls2 4
countt calls 4
memorize calls2 5
countt calls 5
memorize calls2 6
countt calls 6
memorize calls2 7
countt calls 7
memorize calls2 8
countt calls 8
memorize calls2 9
countt calls 9
memorize calls2 10
countt calls 10
memorize calls2 11
countt calls 11
memorize calls2 12
memorize calls2 13
memorize calls2 14
memorize calls2 15
memorize calls2 16
memorize calls2 17
memorize calls2 18
memorize calls2 19
memorize calls2 20
memorize calls2 21
memorize calls2 22
memorize calls2 23
memorize calls2 24
memorize calls2 25
1892
0
25

最佳答案

每个装饰器都会分配一个新函数wrapper,名称为f3,这意味着有3个不同的函数被调用:原始的f3,从 countt 返回的 wrapper 和从 memorize 返回的 wrapper。在最后几行中,print(f3...) 引用了memorize 中的wrapper。但在 counttwrapper 内部,wrapper.calls += 1 引用了 countt 中的 wrapper 而不是内存 中的那个。因此,您看不到 wrapper.calls += 1 的效果,因为您正在查看错误的函数对象。但是,如果您检查 f3.__wrapped__.calls,您将看到正确的值 (11)。

最终的f3(memorize中的wrapper)甚至有一个calls属性的原因是因为 memorize 中的 @wraps 将该属性从 wrappercountt 复制到 wrapper来自记住

关于python - 一个函数有两个装饰器,后一个函数没有按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41278742/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com