考虑代码段
import something
import sys
print(sys.version)
def f(a):
b = a
if a==1:
import something
b *= something.value # <<<<<
return b
print(f(1))
print(f(2))
其中模块something
定义value = 1
。使用Python 3.6.7运行该脚本,调用f(1)
成功,但调用f(2)
失败,但有一个例外:
UnboundLocalError: local variable 'something' referenced before assignment
在标记为<<<<<
的行中。我真的不明白。我在Python 2.7中发现了同样的问题,所以我敢打赌这不是简单的回归,而是与Python处理此类本地导入的方式紧密相关。我在文档中找不到任何提示。有人解释吗?
答案 0 :(得分:7)
import x
语句有两件事*
您的函数仅在something
时将模块something
分配给变量 a == 1
。如果为a != 1
,则即使已加载模块,也未将其分配给变量,因此无法对其进行引用。
这就是为什么您的操作失败。这也是为什么您试图做的事情绝对没有优势的原因,因为模块仅在首次导入时才加载并运行。随后的所有时间都只是在执行步骤2。
您的代码未引用全局something
的原因是因为python会覆盖全局名称,即使相同名称的局部变量出现在函数中的任何位置,即使从未到达也是如此。以下功能f
与您的功能类似。
x = 1
def f(y):
if False:
x = y
return x
解决方案是不要同时使用x
作为局部变量和全局变量。
答案 1 :(得分:2)
如果在给定范围内分配了变量,则该变量在该范围内是本地的。如果该分配是有条件的,并且您可以运行代码(例如它永远不会发生)(或在分配给它之后在该作用域中被引用),则您将得到此异常。相同的较小示例:
def f():
if False:
a = 1
print(a)
a = 1
f()
还有强制性的FAQ link。