如果符号是python函数的关闭似乎有问题 引用的对象已分配:
def outer():
p = []
def gen():
def touch(e):
if e[0] == 'add':
p.append(e);
elif e[0] == 'rem':
p = [ x for x in p if not (x[1] == e[1]) ]
return touch
f = gen()
for i in [["add","test1"],["add","test2"],["rem","test2"],["rem","test1"]]:
f(i)
outer();
结果是:
Traceback (most recent call last):
File "b.py", line 22, in <module>
outer();
File "b.py", line 20, in outer
f(i)
File "b.py", line 14, in touch
p.append(e);
UnboundLocalError: local variable 'p' referenced before assignment
如果我只是为了测试,请替换:
- p = [ x for x in p if not (x[1] == e[1]logig is) ]
+ a = [ x for x in p if not (x[1] == e[1]) ]
错误消失了,但是代码不是我想要的。 python闭包/嵌套函数是否有上述行为?我是否需要包装数组以在对象内部进行修改并仅调用函数?
另一方面,这有效:
class o():
def __init__(self):
self.p = []
def add(self,e):
self.p.append(e);
def rem(self,e):
self.p = [ x for x in self.p if not (x[1] == e[1]) ]
def outer():
p = o()
def gen():
def touch(e):
if e[0] == 'add':
p.add(e);
elif e[0] == 'rem':
p.rem(e)
return touch
f = gen()
for i in [["add","test1"],["add","test2"],["rem","test2"],["rem","test1"]]:
f(i)
outer();
答案 0 :(得分:2)
因为要在p
内分配touch
,所以它成为touch
中的局部变量,并有效地“隐藏”了所有其他名称p
。为了告诉Python您实际上要引用p
中的outer
,应使用nonlocal p
,例如:
def outer():
p = []
def touch(e):
# The following line is required to refer to outer's p
nonlocal p
if e[0] == 'add':
p.append(e)
elif e[0] == 'rem':
p = [ x for x in p if not (x[1] == e[1]) ]
for i in [["add","test1"],["add","test2"],["rem","test2"],["rem","test1"]]:
touch(i)
outer()
您的第二个示例之所以有效,是因为在两种p
情况下都引用了touch
的属性,而不是进行赋值(p = ...
)。
请参见nonlocal
in the Python reference documentation,scopes的参考文档和PEP 3104,其中提出了nonlocal
语法。 nonlocal
仅存在于Python 3中,但如果需要使用Python 2,则存在there is a workaround。