问题描述
我理解Python中局部变量和全局变量的概念,但我只是有一个疑问,为什么错误在下面的代码中出现。 Python一行一行地执行代码,所以它不知道a是否是局部变量,直到它读取第5行。是否Python返回一行并在它尝试执行第5行后将其标记为错误?
a = 0
def test():
打印一个#line 4,错误:局部变量' a'在转让前引用
a = 0 #line 5
test()
$ $ p $
a = 0
def test1():
print (a)
test1()
打印 0
。因此,调用这个函数并没有问题,但是在下一个函数中:
$ b $ pre $ def c test2():
print( a)#错误:在赋值前引用局部变量'a'
= 0
test2()
我们得到一个错误:
Traceback(最近一次调用最后一次):
文件< stdin>,第1行,位于< module>
文件stdin>,第2行,在test2中
UnboundLocalError:赋值前引用的局部变量'a'
反汇编
我们可以反汇编这两个函数(第一个 Python 2 ):
>>> import dis
>>> disdis(test1)
2 0 LOAD_GLOBAL 0(a)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0(无)
8 RETURN_VALUE
我们看到第一个函数自动加载全局 a
,而第二个功能:
>>> disdis(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(无)
14 RETURN_VALUE
在它内部分配 a
,从本地尝试LOAD_FAST(作为优化问题,因为函数在运行之前预先编译为字节码)。
如果我们在 Python 3 中执行此操作,我们会看到几乎相同的效果:
>>> test2()
Traceback(最近一次调用最后一次):
在< module>中,第1行的文件< stdin>
文件stdin>,第2行,在test2中
UnboundLocalError:在赋值之前引用的局部变量'a'
>>>
>>> import dis
>>> disdis(test1)
2 0 LOAD_GLOBAL 0(打印)
3 LOAD_GLOBAL 1(a)
6 CALL_FUNCTION 1(1位置,0个关键字对)
9 POP_TOP
10 LOAD_CONST 0(无)
13 RETURN_VALUE
>>> dis.dis()#反汇编上次堆栈跟踪
2 0 LOAD_GLOBAL 0(print)
- > 3 LOAD_FAST 0(a)
6 CALL_FUNCTION 1(1位置,0个关键字对)
9 POP_TOP
3 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本地与全局变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!