[英]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 here I want clear list a inside a decorator *2 so here must be a new list a inside outer *1 这里我想要一个装饰器里面的清晰列表 a *2 所以这里必须是一个新的列表 a inside outer
Is it posible to clear list a, in global scope?是否可以清除全局 scope 中的列表 a? If yes, how do it correct.
如果是,如何纠正。
It is possible if you define the decorator as a class:如果您将装饰器定义为 class,则有可能:
(tested using Python 3.11) (使用 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
does not exist at the global scope, rather as the cell_contents
attribute of the first element of test.__closure__
. a
在全局 scope 中不存在,而是作为test.__closure__
的第一个元素的cell_contents
属性存在。 You can reset it to an empty list, but I don't recommend modifying closures like this.您可以将其重置为空列表,但我不建议像这样修改闭包。
>>> test()
TEST
['work']
>>> test()
TEST
['work', 'work']
>>> test.__closure__[0].cell_contents = []
>>> test()
TEST
['work']
You should probably instead define a class with a list
-valued instance attribute instead of using a closure.您可能应该使用
list
值实例属性而不是使用闭包来定义 class。
You can add a parameter to the wrapper function specifying whether to clear a
before/after the original function executes.您可以向包装器 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
Result:结果:
TEST
['work']
TEST
[]
TEST
['work']
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.