我在这里使用 python2.7:
import time
def foo():
print time.time() # EXCEPTION THROWN HERE
import time
。引发异常:
UnboundLocalError: local variable 'time' referenced before assignment
如果我删除重新导入:
import time
def foo():
print time.time() # WORKS AS EXPECTED
#import time
。一切都按预期进行。很明显,当调用函数时,有关后续导入的某些内容会影响局部变量表,从函数开始执行的那一刻起 - 而不是从包含点开始:
import time
def foo():
global time
print time.time() # WORKS AS EXPECTED
import time
。奇怪。
出现这种情况是因为工程师在一个大型方法的顶部添加了对 time.time() 的调用,但没有看到它在函数中间导入(由一位早已离开的工程师导入)。我不是在寻求有关如何解决问题的指导 - 这是可悲的显而易见的(并且还将涉及追捕这样做的人,提供必要的毒品耳光。
我很好奇这个机制,为什么这样做,以及我可以检查系统的哪些部分来查看它的所有运行情况。
问题与import
无关。它只是关于全局变量与局部变量。请参阅此最小示例:
x = 0
def access():
print(x)
def shadow():
print(x)
x = 1
现在让我们拆解函数并看一下字节码:
access()
0 LOAD_GLOBAL 0 (print)
3 LOAD_GLOBAL 1 (x)
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
您可以看到符号x
被查找为全局变量LOAD_GLOBAL 1 (x)
shadow()
0 LOAD_GLOBAL 0 (print)
3 LOAD_FAST 0 (x)
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 POP_TOP
10 LOAD_CONST 1 (1)
13 STORE_FAST 0 (x)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
当您在函数体中重新定义变量x
时,我们得到的是这个字节码:LOAD_FAST 0 (x)
。因此,即使此时尚未定义,它也会作为局部变量进行查找。由于没有定义局部变量x
但我们得到了UnboundLocalError
,即未定义的局部变量。
在您的示例中,模块time
是全局/局部变量。