python - 为什么在函数中使用模块后重新导入会抛出异常?

标签 python import global-variables importerror local-variables

我在这里欺骗 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

现在让我们反汇编函数并看一下字节码:

访问()

 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)

阴影()

 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 是全局/局部变量。

关于python - 为什么在函数中使用模块后重新导入会抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36096705/

相关文章:

java - 除了 Java 文件的开头之外,是否可以在任何地方使用 import 语句?

python - blender 和 conda

javascript - 如何在稍后的测试中重用产生的值

python - 将矩形函数拟合到实际数据点

python - 计算多列中的零

python - 使用 QClipboard,如何复制富文本并将其降级为文本编辑器的纯文本?

ubuntu - 在 Ubuntu 中从 CSV 复制到 Postgres

python - Django Rest Framework Api 查看 GET

c++ - 在测试中测试 C++ 全局变量的最佳方法

c++ - 全局变量不好吗?