有没有办法修改闭包内的其中一个变量的绑定值?看一下这个例子来更好地理解它.
def foo(): var_a = 2 var_b = 3 def _closure(x): return var_a + var_b + x return _closure localClosure = foo() # Local closure is now "return 2 + 3 + x" a = localClosure(1) # 2 + 3 + 1 == 6 # DO SOME MAGIC HERE TO TURN "var_a" of the closure into 0 # ...but what magic? Is this even possible? # Local closure is now "return 0 + 3 + x" b = localClosure(1) # 0 + 3 +1 == 4
recursive.. 26
由于非局部的魔力,在python 3中很有可能.
def foo(): var_a = 2 var_b = 3 def _closure(x, magic = None): nonlocal var_a if magic is not None: var_a = magic return var_a + var_b + x return _closure localClosure = foo() # Local closure is now "return 2 + 3 + x" a = localClosure(1) # 2 + 3 + 1 == 6 print(a) # DO SOME MAGIC HERE TO TURN "var_a" of the closure into 0 localClosure(0, 0) # Local closure is now "return 0 + 3 + x" b = localClosure(1) # 0 + 3 +1 == 4 print(b)
卫生署!我想说我不会.它对我来说仍然看起来很奇怪和黑客.关于可选参数改变值的全部内容.整件事应该是一堂课.但无论如何,我离题了. (4认同)
Greg Hewgill.. 21
我不认为在Python中有任何方法可以做到这一点.定义闭包时,将捕获封闭范围中变量的当前状态,并且不再具有可直接引用的名称(从闭包外部).如果foo()
再次调用,则新闭包将与封闭范围具有不同的变量集.
在您的简单示例中,您可能最好使用类:
class foo: def __init__(self): self.var_a = 2 self.var_b = 3 def __call__(self, x): return self.var_a + self.var_b + x localClosure = foo() # Local closure is now "return 2 + 3 + x" a = localClosure(1) # 2 + 3 + 1 == 6 # DO SOME MAGIC HERE TO TURN "var_a" of the closure into 0 # ...but what magic? Is this even possible? localClosure.var_a = 0 # Local closure is now "return 0 + 3 + x" b = localClosure(1) # 0 + 3 +1 == 4
如果你使用这种技术,我将不再使用该名称,localClosure
因为它不再是一个闭包.但是,它的工作原理与之相同.
由于非局部的魔力,在python 3中很有可能.
def foo(): var_a = 2 var_b = 3 def _closure(x, magic = None): nonlocal var_a if magic is not None: var_a = magic return var_a + var_b + x return _closure localClosure = foo() # Local closure is now "return 2 + 3 + x" a = localClosure(1) # 2 + 3 + 1 == 6 print(a) # DO SOME MAGIC HERE TO TURN "var_a" of the closure into 0 localClosure(0, 0) # Local closure is now "return 0 + 3 + x" b = localClosure(1) # 0 + 3 +1 == 4 print(b)
我不认为在Python中有任何方法可以做到这一点.定义闭包时,将捕获封闭范围中变量的当前状态,并且不再具有可直接引用的名称(从闭包外部).如果foo()
再次调用,则新闭包将与封闭范围具有不同的变量集.
在您的简单示例中,您可能最好使用类:
class foo: def __init__(self): self.var_a = 2 self.var_b = 3 def __call__(self, x): return self.var_a + self.var_b + x localClosure = foo() # Local closure is now "return 2 + 3 + x" a = localClosure(1) # 2 + 3 + 1 == 6 # DO SOME MAGIC HERE TO TURN "var_a" of the closure into 0 # ...but what magic? Is this even possible? localClosure.var_a = 0 # Local closure is now "return 0 + 3 + x" b = localClosure(1) # 0 + 3 +1 == 4
如果你使用这种技术,我将不再使用该名称,localClosure
因为它不再是一个闭包.但是,它的工作原理与之相同.
我找到了Greg的另一个答案答案,稍微不那么冗长,因为它使用Python 2.1的自定义函数属性(可以方便地从它们自己的函数内部访问).
def foo(): var_b = 3 def _closure(x): return _closure.var_a + var_b + x _closure.func_dict['var_a'] = 2 return _closure localClosure = foo() # Local closure is now "return 2 + 3 + x" a = localClosure(1) # 2 + 3 + 1 == 6 # DO SOME MAGIC HERE TO TURN "var_a" of the closure into 0 # ...but what magic? Is this even possible? # apparently, it is localClosure.var_a = 0 # Local closure is now "return 0 + 3 + x" b = localClosure(1) # 0 + 3 +1 == 4
以为我会发布完整性.无论如何干杯.
我们做了以下事情.我认为这比其他解决方案简单.
class State: pass def foo(): st = State() st.var_a = 2 st.var_b = 3 def _closure(x): return st.var_a + st.var_b + x def _set_a(a): st.var_a = a return _closure, _set_a localClosure, localSetA = foo() # Local closure is now "return 2 + 3 + x" a = localClosure(1) # 2 + 3 + 1 == 6 # DO SOME MAGIC HERE TO TURN "var_a" of the closure into 0 localSetA(0) # Local closure is now "return 0 + 3 + x" b = localClosure(1) # 0 + 3 +1 == 4 print a, b