Python 局部变量与全局变量

标签 python scope runtime global-variables local-variables

我理解 Python 中局部变量和全局变量的概念,但我有一个问题,为什么错误会像下面的代码那样出现。 Python 逐行执行代码,因此它直到读取第 5 行才知道 a 是局部变量。Python 是否会在尝试执行第 5 行后返回一行并将其标记为错误?

a=0

def test():
    print a  #line 4, Error : local variable 'a' referenced before assignment
    a=0      #line 5

test()

最佳答案

设置和测试

为了分析您的问题,让我们创建两个独立的测试函数来复制您的问题:

a=0

def test1():
    print(a)

test1()

打印0。所以,调用这个函数是没有问题的,但是在下一个函数上:

def test2():
    print(a)  # Error : local variable 'a' referenced before assignment
    a=0  

test2()

我们得到一个错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test2
UnboundLocalError: local variable 'a' referenced before assignment

反汇编

我们可以反汇编这两个函数(首先是Python 2):

>>> import dis
>>> dis.dis(test1)
  2           0 LOAD_GLOBAL              0 (a)
              3 PRINT_ITEM          
              4 PRINT_NEWLINE       
              5 LOAD_CONST               0 (None)
              8 RETURN_VALUE        

我们看到第一个函数自动加载全局a,而第二个函数:

>>> dis.dis(test2)
  2           0 LOAD_FAST                0 (a)
              3 PRINT_ITEM          
              4 PRINT_NEWLINE       

  3           5 LOAD_CONST               1 (0)
              8 STORE_FAST               0 (a)
             11 LOAD_CONST               0 (None)
             14 RETURN_VALUE      

看到 a 已在其中分配,尝试从本地加载 LOAD_FAST(作为优化问题,因为函数在运行前已预编译为字节码。)

如果我们在 Python 3 中运行它,我们会看到几乎相同的效果:

>>> test2()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test2
UnboundLocalError: local variable 'a' referenced before assignment
>>> 
>>> import dis
>>> dis.dis(test1)
  2           0 LOAD_GLOBAL              0 (print) 
              3 LOAD_GLOBAL              1 (a) 
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
              9 POP_TOP              
             10 LOAD_CONST               0 (None) 
             13 RETURN_VALUE     

>>> dis.dis() # disassembles the last stack trace
  2           0 LOAD_GLOBAL              0 (print) 
    -->       3 LOAD_FAST                0 (a) 
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
              9 POP_TOP              

  3          10 LOAD_CONST               1 (0) 
             13 STORE_FAST               0 (a) 
             16 LOAD_CONST               0 (None) 
             19 RETURN_VALUE        

我们看到我们的错误再次出现在 LOAD_FAST 上。

关于Python 局部变量与全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22439752/

相关文章:

python - 如果满足某些 GroupBy 条件,则从原始 Pandas 数据框中删除行

python - 检查嵌套的字典值?

javascript - 编写函数的不同方式会在 JavaScript 中带来不良影响吗?

ruby-on-rails - Rails 5 - 使用 Pundit Scopes 和 Statesman 状态机 : structurally incompatible?

swift - Swift 3.1 中 `do` block 内的标识符识别

java - 如何在 Java 中更改光标图标?

java - Eclipse 未找到可执行 Jar 的库

python - 如何在 python 中用整数制作网格?

两个时间序列的python聚合

C++ Win32 不依赖 C 运行时库,但有 malloc,免费 atd