![](/img/trans.png)
[英]Why does a global list variable is updated in global scope inside a function without using global line?
[英]Clear list inside decorator from global scope
def outer(func):
a = []
def inner():
func()
a.append('work')
print(a)
return inner
@outer
def test():
print('TEST')
test()
test()
# *1
test() # *2
*1 这里我想要一个装饰器里面的清晰列表 a *2 所以这里必须是一个新的列表 a inside outer
是否可以清除全局 scope 中的列表 a? 如果是,如何纠正。
如果您将装饰器定义为 class,则有可能:
(使用 Python 3.11 测试)
class Outer:
def __init__(self):
self.a = []
def reset(self):
self.a = []
def __call__(self, fn):
def inner():
fn()
self.a.append('work')
print(self.a)
return inner
outer = Outer()
@outer
def test():
print('TEST')
test()
# TEST
# ['work']
test()
# TEST
# ['work', 'work']
print(f'before-reset {outer.a}')
# before-reset ['work', 'work']
outer.reset()
print(f'after-reset {outer.a}')
# after-reset []
test()
# TEST
# ['work']
print(f'after-next test() {outer.a}')
# after-next test() ['work']
a
在全局 scope 中不存在,而是作为test.__closure__
的第一个元素的cell_contents
属性存在。 您可以将其重置为空列表,但我不建议像这样修改闭包。
>>> test()
TEST
['work']
>>> test()
TEST
['work', 'work']
>>> test.__closure__[0].cell_contents = []
>>> test()
TEST
['work']
您可能应该使用list
值实例属性而不是使用闭包来定义 class。
您可以向包装器 function 添加一个参数,指定是否在原始 function a
之前/之后清除。
def outer(func):
a = []
def inner(clear=False):
func()
a.clear() if clear else a.append('work')
print(a)
return inner
@outer
def test():
print('TEST')
test()
test(clear=True)
# *1
test() # *2
结果:
TEST
['work']
TEST
[]
TEST
['work']
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.