您正在函数中设置局部变量。分配给函数中的名称会将其标记为本地名称,除非您特别告诉 Python 编译器。xsetter()
在 Python 3 中,您可以使用关键字显式标记x为非本地:nonlocal
def make_adder_and_setter(x):
def setter(n):
nonlocal x
x = n
return (lambda y: x + y, setter)
Nowx被标记为自由变量,并在分配时在周围范围内查找。
在 Python 2 中,您不能将 Python 本地标记为这样。您唯一的其他选择是标记x为global. 您必须使用技巧来更改位于周围范围内的可变对象所包含的值。
例如,函数上的属性setter会起作用;setter在范围内是本地的make_adder_and_setter(),该对象上的属性将对任何有权访问的对象可见setter:
def make_adder_and_setter(x):
def setter(n):
setter.x = n
setter.x = x
return (lambda y: setter.x + y, setter)
另一个技巧是使用可变容器,例如列表:
def make_adder_and_setter(x):
x = [x]
def setter(n):
x[0] = n
return (lambda y: x[0] + y, setter)
在这两种情况下,您都不再分配本地名称;第一个示例对setter对象使用属性分配,第二个示例更改x列表,而不是分配给x自身。