提出的重复问题,
Scope of variables in python decorators - changing parameters
wrapper_repeat
考虑
nbrTimes
作为一个局部变量,如何
nonlocal
可能是用来让它识别
定义人
repeat
import functools
def repeat(nbrTimes=2):
'''
Define parametrized decorator with arguments
Default nbr of repeats is 2
'''
def real_repeat(func):
"""
Repeats execution 'nbrTimes' times
"""
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
nonlocal nbrTimes
while nbrTimes != 0:
nbrTimes -= 1
return func(*args, **kwargs)
return wrapper_repeat
return real_repeat
@repeat(2)
def display(x):
print("displaying:", x)
display("foo")
display("bar")
display("baz")
结果:
displaying: foo
displaying: bar
“foo”和“bar”各显示一次,“baz”显示零次。我想这不是我想要的行为。
前两个电话
display
由于错误而未能重复
return func(*args, **kwargs)
在你的
while
包装器\u重复
立即终止,并且
将会发生。因此,任何修饰函数都不会重复一次以上。一种可能的解决办法是移除
return
只需调用函数。
import functools
def repeat(nbrTimes=2):
'''
Define parametrized decorator with arguments
Default nbr of repeats is 2
'''
def real_repeat(func):
"""
Repeats execution 'nbrTimes' times
"""
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
nonlocal nbrTimes
while nbrTimes != 0:
nbrTimes -= 1
func(*args, **kwargs)
return wrapper_repeat
return real_repeat
@repeat(2)
def display(x):
print("displaying:", x)
display("foo")
display("bar")
display("baz")
结果:
displaying: foo
displaying: foo
在您的decorator的所有实例中共享,这要感谢
非局部的
. 一旦
display("foo")
NBR次
如果设置为零,则即使在调用完成后,它仍保持为零。
display("bar")
和
display("baz")
会处决他们的装饰师,明白吗
NBR次
为零,并且在根本不调用修饰函数的情况下终止。
所以事实证明你没有
希望
循环计数器必须是非局部的。但这意味着你不能使用
NBR次
为此目的。尝试创建基于
NBR次
import functools
def repeat(nbrTimes=2):
'''
Define parametrized decorator with arguments
Default nbr of repeats is 2
'''
def real_repeat(func):
"""
Repeats execution 'nbrTimes' times
"""
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
times = nbrTimes
while times != 0:
times -= 1
func(*args, **kwargs)
return wrapper_repeat
return real_repeat
@repeat(2)
def display(x):
print("displaying:", x)
display("foo")
display("bar")
display("baz")
结果:
displaying: foo
displaying: foo
displaying: bar
displaying: bar
displaying: baz
displaying: baz
for
循环而不是
虽然
.
import functools
def repeat(nbrTimes=2):
'''
Define parametrized decorator with arguments
Default nbr of repeats is 2
'''
def real_repeat(func):
"""
Repeats execution 'nbrTimes' times
"""
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
for _ in range(nbrTimes):
func(*args, **kwargs)
return wrapper_repeat
return real_repeat
@repeat(2)
def display(x):
print("displaying:", x)
display("foo")
display("bar")
display("baz")