以下代码引发UnboundLocalError
:
def foo():
i = 0
def incr():
i += 1
incr()
print(i)
foo()
有没有办法实现这个目标?
答案 0 :(得分:30)
使用nonlocal
声明
def foo():
i = 0
def incr():
nonlocal i
i += 1
incr()
print(i)
foo()
有关python 3.x中添加的新语句的更多信息,请转到https://docs.python.org/3/reference/simple_stmts.html#the-nonlocal-statement
答案 1 :(得分:20)
您可以使用i
作为参数:
def foo():
i = 0
def incr(i):
return i + 1
i = incr(i)
print(i)
foo()
答案 2 :(得分:9)
请参阅9.2. Python Scopes and Namespaces:
如果没有
global
语句生效 - 名称的赋值总是进入最里面的范围。
此外:
global
语句可用于表示特定变量存在于全局范围内,应该在那里反弹;nonlocal
语句表明特定变量存在于封闭范围中,应该在那里反弹。
你有很多解决方案:
i
作为参数✓(我会选择这个)nonlocal
关键字请注意,在Python2.x中,您可以访问非本地变量,但无法更改它们。
答案 3 :(得分:4)
在Python中,int是不可变的。所以你可以将你的int放在一个可变对象中。
def foo():
i = 0
obj = [i]
def incr(obj):
obj[0]+=1
incr(obj)
print(obj[0])
foo()
答案 4 :(得分:2)
您可以将i
设为全局并使用它。
i = 0
def foo():
def incr():
global i
i += 1
incr()
print(i)
foo()
但最首选的方法是将i
作为参数传递给incr
def foo():
i = 0
def incr(arg):
arg += 1
return arg
i = incr(i)
print(i)
foo()
答案 5 :(得分:0)
你也可以使用lambda函数:
def foo():
i=0
incr = lambda x: x+1
print incr(i)
foo()
我认为代码更清洁
答案 6 :(得分:0)
在这种情况下,简单的函数属性不起作用。
>>> def foo():
... foo.i = 0
... def incr():
... foo.i +=1
... incr()
... print(foo.i)
...
>>>
>>>
>>> foo()
1
>>> foo()
1
>>> foo()
1
每次拨打0
时,您都会将foo.i指定给foo
。
最好使用hassattr
。但是代码变得更加复杂。
>>> def foo():
... if not hasattr(foo, 'i'):
... foo.i = 0
... def incr():
... foo.i += 1
... return foo.i
... i = incr()
... print(i)
...
>>>
>>>
>>> foo()
1
>>> foo()
2
>>> foo()
3
你也可以尝试这个想法:
>>> def foo():
... def incr():
... incr.i += 1
... return incr.i
... incr.i = 0
... return incr
...
>>> a = foo()
>>> a()
1
>>> a()
2
>>> a()
3
>>> a()
4
将你装入装饰师可能会更方便。