我有以下模块:
main.py
import my_import
my_import.a_func()
my_import.py
FOO = "foo"
BAR = []
def a_func():
BAR.append("bar") #ok
FOO = FOO + "foo" #UnboundLocalError:
#local variable 'FOO' referenced before assignment
这可能是由于导入,但是如何?
[编辑]
从答案我得到的不是导入的crulpit,但是后续仍然很奇怪:
FOO = "foo"
BAR = []
def a_func():
BAR.append("bar")
print(FOO)
a_func()
- >打印“foo”
FOO = "foo"
BAR = []
def a_func():
BAR.append("bar")
print(FOO)
FOO = FOO + "foo"
a_func()
- >失败,“UnboundLocalError:在赋值之前引用了局部变量'FOO'并且没有打印”foo“
看起来解释器在实际运行代码之前正在查找当前作用域中的赋值。
答案 0 :(得分:5)
当Python解析函数定义时,它会记录赋值语句左侧的所有变量名,例如
FOO = FOO + "foo"
它将所有此类变量名称注册为局部变量。
让我强调一下,赋值语句会导致Python在解析函数定义时将FOO
注册为局部变量,而不是在调用函数时。所以稍后,当调用该函数时,即使对在赋值之前发生的FOO
的引用仍然引用局部变量并且可以引发UnboundLocalError
。
def a_func():
BAR.append("bar")
print(FOO) #<--- "Freaky" UnboundLocalError occurs here!
FOO = FOO + "foo"
所以在a_func
内,FOO是一个局部变量。在没有print(FOO)
语句的情况下,Python到达赋值并首先评估右侧。遇到变量名称FOO
,将其识别为局部变量并询问其值是多少?它没有价值!所以它引发了UnboundLocalError
。
要解决此问题,请使用global FOO
声明FOO
内的a_func
引用全局变量:
FOO = "foo"
BAR = []
def a_func():
global FOO
BAR.append("bar") #ok
FOO = FOO + "foo" assignment
相比之下,BAR.append('bar')
有效,因为Python首先查找变量BAR
- 它不认为它是局部变量,因为没有赋值BAR = ...
。它在全局范围内找到BAR
,然后查找其append方法,然后改变BAR
。因此,您可以改变BAR
但不能分配给FOO
(没有global FOO
语句。)
答案 1 :(得分:2)
不,它与导入无关。它也会发生在单个模块或脚本中,即使在交互式解释器中也是如此。
最小的例子是
a = 1
def f():
a = a + 1
此分配使a
成为局部变量。在这种情况下,全局的一个被遮蔽,因此无法访问。
如果您想更改全局版本,可以使用global
解决此问题:
a = 1
def f():
global a
a = a + 1
如果要在本地保留更改,请使用或使用不同名称的本地变量:
a = 1
def f():
b = a
b = b + 1
答案 2 :(得分:0)
我可能是错的,但FOO和BAR的范围可能是问题吗?看起来好像您已进入不同的范围。尝试将方法中的FOO和BAR标记为全局。