我有一个简单的例子:
def func1():
local_var = None
def func(args):
print args,
print "local_var:", local_var
local_var = "local"
func("first")
func("second")
func1()
我希望输出为:
first local_var: None second local_var: local
但是,我的实际输出是:
first local_var: Traceback (most recent call last): File "test.py", line 13, in func1() File "test.py", line 10, in func1 func("first") File "test.py", line 6, in func print "local_var:", local_var UnboundLocalError: local variable 'local_var' referenced before assignment
我对python范围规则的理解要求这应该按预期工作。我有其他代码,这可以按预期工作,但减少一个非工作代码片段到它上面的小部分情况也不起作用。所以我很难过。
答案 0 :(得分:9)
local_var
中对func
的分配使其本地到func
- 因此print
语句引用“非常本地”变量在它被分配之前变量,正如例外所述。正如jtb所说,在Python 3中你可以使用nonlocal
来解决这个问题,但是使用print
语句从代码中可以清楚地知道你在Python 2中工作.Python 2中的传统解决方案是确保赋值不是一个名字,因此不会使变量比你想要的更加局部,例如:
def func1():
local_var = [None]
def func(args):
print args,
print "local_var:", local_var[0]
local_var[0] = "local"
func("first")
func("second")
func1()
索引的赋值不是一个简单的名称,因此不会影响局部性,因为Python 2.2嵌套的内部函数完全可以接受引用到外部包含函数的本地变量,这就是所有这个版本(分配到裸名称是一个与将引用到变量不同的问题)。
答案 1 :(得分:1)
在Python 3.0之前,函数无法写入外部作用域中的非全局变量。 Python3引入了nonlocal
关键字,可以让它工作。您可以在nonlocal local_var
定义的顶部添加func()
以获得您期望的输出。请参阅PEP 3104。
如果您不使用Python 3,则必须将变量设为全局变量,或以某种方式将其传递给函数。
答案 2 :(得分:1)
3.0之前解决此问题的标准方法是
def func1():
local_var = [None]
def func(args):
print args,
print "local_var:", local_var[0]
local_var[0] = "local"
func("first")
func("second")
func1()
答案 3 :(得分:1)
Python的范围规则在相关问题中进行了讨论和解释: