Python 局部变量与全局变量 [英] Python local vs global variables

查看:43
本文介绍了Python 局部变量与全局变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解 Python 中局部变量和全局变量的概念,但我只是有一个问题,为什么错误会在以下代码中以这种方式出现.Python 一行一行地执行代码,所以它直到读取第 5 行才知道 a 是局部变量.Python 在尝试执行第 5 行后是否会返回一行并将其标记为错误?

a=0定义测试():打印#line 4,错误:赋值前引用了局部变量a"a=0 #第5行测试()

解决方案

设置和测试

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

a=0def test1():打印(一)测试1()

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

def test2():print(a) # 错误:赋值前引用了局部变量a"a=0测试2()

我们得到一个错误:

回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中文件<stdin>",第 2 行,在 test2 中UnboundLocalError:赋值前引用了局部变量a"

拆解

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

<预><代码>>>>导入文件>>>dis.dis(test1)2 0 LOAD_GLOBAL 0 (a)3 PRINT_ITEM4 PRINT_NEWLINE5 LOAD_CONST 0(无)8 RETURN_VALUE

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

<预><代码>>>>dis.dis(test2)2 0 LOAD_FAST 0 (a)3 PRINT_ITEM4 PRINT_NEWLINE3 5 LOAD_CONST 1 (0)8 STORE_FAST 0 (a)11 LOAD_CONST 0 (无)14 RETURN_VALUE

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

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

<预><代码>>>>测试2()回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中文件<stdin>",第 2 行,在 test2 中UnboundLocalError:赋值前引用了局部变量a">>>>>>导入文件>>>dis.dis(test1)2 0 LOAD_GLOBAL 0(打印)3 LOAD_GLOBAL 1 (a)6 CALL_FUNCTION 1(1 个位置,0 个关键字对)9 POP_TOP10 LOAD_CONST 0 (无)13 RETURN_VALUE>>>dis.dis() # 反汇编最后一个堆栈跟踪2 0 LOAD_GLOBAL 0(打印)-->3 LOAD_FAST 0 (a)6 CALL_FUNCTION 1(1 个位置,0 个关键字对)9 POP_TOP3 10 LOAD_CONST 1 (0)13 STORE_FAST 0 (a)16 LOAD_CONST 0 (无)19 RETURN_VALUE

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

I understand the concept of local and global variables in Python, but I just have a question about why the error comes out the way it is in the following code. Python execute the codes line by line, so it does not know that a is a local variable until it reads line 5. Does Python go back one line and tag it as an error after it tries to execute line 5?

a=0

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

test()

解决方案

Setup and Testing

To analyze your question, let's create two separate test functions that replicate your issue:

a=0

def test1():
    print(a)

test1()

prints 0. So, calling this function is not problematic, but on the next function:

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

test2()

We get an error:

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

Disassembly

We can disassemble the two functions (first 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        

And we see that the first function automatically loads the global a, while the second function:

>>> 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      

seeing that a is assigned inside it, attempts to LOAD_FAST from the locals (as a matter of optimization, as functions are pre-compiled into byte-code before running.)

If we run this in Python 3, we see nearly the same effect:

>>> 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        

We see our error is on the LOAD_FAST again.

这篇关于Python 局部变量与全局变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆