谈谈Python for循环的作用域

对于从其他语言转到Python的人来说,下面这段代码显得很诡异:

1

2

3

for i in range(3):

    print(i)

print(i)

你期望的是i变量不存在报错,而实际上打印结果是:

1

2

3

4

0

1

2

2

这是因为,在Pyhton中,是没有block这个概念的。

Python中的作用域只有四种,即LEGB规则:

L, local – 在lambda函数内或者def函数内部的变量

E, Enclosing-function – 闭包的作用域(了解Python的闭包可以看《闭包初探》)

G,Global – 全局作用域

B, Build-in – 内建作用域

举个例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

In [3]: def func():

   ...:     a = 1 # Local

   ...:     def inner():

   ...:         print(a) # 和外部函数的a构成了闭包

   ...:         foo = 'hello' # 这里foo是local局部变量

   ...:         for foo in ["hello", "python"]: # for循环并没有作用域,foo也是局部变量,会覆盖上面的foo

   ...:             print(foo)

   ...:         print(foo) # 局部变量foo依然存在,打印"python"

   ...:         global s  # s变成全局变量

   ...:         s = 12

   ...:     inner()

   ...:

 

In [4]: func()

1

hello

python

python

 

In [5]: s

Out[5]: 12

由此看来,for循环的作用域会污染局部作用域,Python2的列表生成式也会有这个副作用,但是已经在Python3中得到了修复。

你可能感兴趣的:(python)