Python作用域问题

2022-01-10 19:43

在使用Python的时候遇到了一些与作用域相关的问题,感觉挺奇怪的,这里简单记录一下

1. for循环变量

for i in range(10):
    t = 0

print(i, t)

按照写C/C++的习惯,这个ti的作用域仅限于for循环内,下面的print(i, t)应该会报错,但是在实际的运行中并没有报错,反而还打印出了值

>>9 0

这算是Python的一个设计选择,设计的时候觉得这样比较方便,stackoverflow上面有一个关于这个问题的讨论,蛮有意思的: scope - Scoping in Python ‘for’ loops - Stack Overflow

Previous proposals to make for-loop variables local to the loop have stumbled on the problem of existing code that relies on the loop variable keeping its value after exiting the loop, and it seems that this is regarded as a desirable feature

2. 函数里面的局部变量与全局变量

这个是我在《Fluent Python》里面看见的一个例子,和上面那个一样也是属于Python关于变量作用域设计的一个特点(feature)。

>>> def f1(a):
...     print(a)
...     print(b)
...
>>> f1(3)
3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in f1
NameError: global name 'b' is not defined

在函数中读取一个局部变量a与一个全局变量b,因为全局变量b我们没有定义,所以函数会报错,只要提前定义b那么就可以啦

>>> b = 6
>>> f1(3)
3
6

但是我们在函数中尝试修改全局变量b会发生什么呢?

>>> b = 6
>>> def f2(a):
...     print(a)
...     print(b)
...     b = 9
...
>>> f2(3)
3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in f2
UnboundLocalError: local variable 'b' referenced before assignment

又报错了,说变量b没有提前声明,但是print(b)却可以正常运行。这是因为Python不要求进行变量声明,但是假定在函数里面赋值的都是局部变量,所以当我们在为b赋值的时候,Python会假定b是局部变量,但是局部变量b并没有创建,所以就出现错误了。要想在函数中修改全局变量加上关键字global就可以啦。