python closure/nested function fail when with assignment to outer array
本问题已经有最佳答案,请猛点这里访问。
如果符号引用分配:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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(); |
结果是:
1 2 3 4 5 6 7 8 | 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 |
如果我只是为了测试而更换:
1 2 | - 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闭包/嵌套函数实现的吗?是否需要包装数组以在对象内进行修改并只调用函数?
另一方面,这项工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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(); |
因为您在
1 2 3 4 5 6 7 8 9 10 11 12 | 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() |
您的第二个示例之所以有效,是因为您在两种情况下都引用
参见python参考文档中的