以下代码提出了UnboundLocalError:
def foo():
i = 0
def incr():
i += 1
incr()
print(i)
foo()
Run Code Online (Sandbox Code Playgroud)
有没有办法实现这个目标?
pig*_*lei 30
使用nonlocal声明
def foo():
i = 0
def incr():
nonlocal i
i += 1
incr()
print(i)
foo()
Run Code Online (Sandbox Code Playgroud)
有关python 3.x中添加的新语句的更多信息,请访问https://docs.python.org/3/reference/simple_stmts.html#the-nonlocal-statement
Kev*_*uan 20
你可以i像这样使用一个参数:
def foo():
i = 0
def incr(i):
return i + 1
i = incr(i)
print(i)
foo()
Run Code Online (Sandbox Code Playgroud)
如果没有
global语句生效 - 名称的赋值总是进入最内层范围.
也:
该
global陈述可用于表明特定变量存在于全球范围内,并应在那里反弹; 该nonlocal陈述表明特定变量存在于封闭范围内,应该在那里反弹.
你有很多解决方案:
i作为参数传递✓(我会选择这个)nonlocal关键字请注意,在Python2.x中,您可以访问非局部变量,但无法更改它们.
人们已经回答了你的问题,但似乎没有人解决为什么会发生这种情况.
以下代码提出了一个问题
UnboundLocalError
那么,为什么呢?让我们从FAQ中引用:
当您对作用域中的变量进行赋值时,该变量将成为该作用域的局部变量,并在外部作用域中隐藏任何类似命名的变量.
在嵌套函数中,您正在与+=运算符执行赋值.这意味着i += 1将近似执行i = i + 1(从绑定的角度来看).因此i,i + 1将在本地范围内搜索表达式(因为它在赋值语句中使用)incr,因为它将无法找到它的函数,从而产生一个UnboundLocalError: reference before assignment.
有很多方法可以解决这个问题,python 3在你可以采用的方法上比python 2更优雅.
这些nonlocal语句告诉Python在foo()名称引用的封闭范围内查找名称(在本例中,在函数范围内):
def foo():
i = 0
def incr():
nonlocal i
i +=1
incr()
print(i)
Run Code Online (Sandbox Code Playgroud)
请记住,函数是第一类对象,因此它们可以存储状态.使用函数属性来访问和改变函数状态,这种方法的好处是它适用于所有 pythons并且不需要global, nonlocal语句.
def foo():
foo.i = 0
def incr():
foo.i +=1
incr()
print(foo.i)
Run Code Online (Sandbox Code Playgroud)
真是最丑陋的一群,但完成了工作:
i = 0
def foo():
def incr():
global i
i += 1
incr()
print(i)
foo()
Run Code Online (Sandbox Code Playgroud)
将参数传递给函数的选项获得相同的结果,但它与在某种意义上改变封闭范围无关nonlocal,global而且更像是所呈现的函数属性.它正在函数中创建一个新的局部变量inc,然后将名称重新绑定到i,i = incr(i)但它确实完成了工作.