Python的作用域和其他语言有所不同,他有几个小窍门来判断作用域。
1. Python里面没有块级别的作用域;只有函数级别的作用域。
比如说,下面这个例子,如果是Java或者其他语言,肯定报错name没有定义。Python里面因为不存在块级别的作用域,因此name直接就输出9了
1
2
3
4
5
|
>>>
for
i
in
range
(
10
):
name
=
i
print
(name)
-
-
-
-
-
-
-
-
-
-
9
|
2. 作用域链的顺序是从内往外找,直到找不到为止
例如
1
2
3
4
5
6
7
8
9
10
11
|
>>>
def
f1():
name
=
'a'
def
f2():
name
=
'b'
print
(name)
f2()
print
(name)
f1()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
b
a
|
3. 函数没有执行之前,作用域已经确定了,作用域链也已经确定了。
例如 f0()执行之前,已经确定了name就是alex,因此不管他如何调用,输出总是alex
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> name
=
'alex'
def
f0():
print
(name)
def
f1():
name
=
'bbb'
f0()
def
f2():
name
=
'eric'
f1()
f2()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
alex
|
下面看几个特殊的例子和语法
比如,我们可以通过下面的方式给列表赋值
1
2
3
4
5
6
7
|
>>> li
=
[x
+
100
for
x
in
range
(
10
)]
print
(li)
li
=
[x
+
100
for
x
in
range
(
10
)
if
x>
6
]
print
(li)
-
-
-
-
-
-
-
-
-
-
-
-
[
100
,
101
,
102
,
103
,
104
,
105
,
106
,
107
,
108
,
109
]
[
107
,
108
,
109
]
|
如果把上面的例子改成lambda表达式,那么因为lambda其实就是函数,他在未执行前是不会执行内部代码的,因此列表里面的每个元素都是函数,当我们()来执行的时候,他会尝试返回X,而X这个时候在10次循环之后已经是9了
1
2
3
4
5
6
7
|
>>>
#li列表里面的元素[函数,函数,函数],函数在没有执行前,内部代码不执行
li
=
[
lambda
:x
for
x
in
range
(
10
)]
print
(li)
print
(li[
0
]())
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
[<function <listcomp>.<
lambda
> at
0x0000019EA4515BF8
>, <function <listcomp>.<
lambda
> at
0x0000019EA4515C80
>, <function <listcomp>.<
lambda
> at
0x0000019EA4515D08
>, <function <listcomp>.<
lambda
> at
0x0000019EA4515D90
>, <function <listcomp>.<
lambda
> at
0x0000019EA4515E18
>, <function <listcomp>.<
lambda
> at
0x0000019EA4515EA0
>, <function <listcomp>.<
lambda
> at
0x0000019EA4515F28
>, <function <listcomp>.<
lambda
> at
0x0000019EA452B048
>, <function <listcomp>.<
lambda
> at
0x0000019EA452B0D0
>, <function <listcomp>.<
lambda
> at
0x0000019EA452B158
>]
9
|
换一种容易理解的写法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
>> li
=
[]
for
i
in
range
(
10
):
def
f1():
return
i
li.append(f1)
#li是列表,内部元素是相同功能的函数
#i=9
print
(i)
## f1 没有调用之前,内部代码不执行;因此li内部都是函数
##真正执行() 时候,他会返回i,内部没有i,往上找,i已经是9了,因此返回9
print
(li[
0
]())
print
(li[
2
]())
9
9
|
如果改成x=i,f1初始化的时候会指定x的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
>>> li
=
[]
for
i
in
range
(
10
):
def
f1(x
=
i):
return
x
li.append(f1)
#li是列表,内部元素是相同功能的函数
#i
print
(i)
## f1 没有调用之前,内部代码不执行;因此li内部都是函数
##真正执行() 时候,他会返回i,内部没有i,往上找,i已经是9了,因此返回9
print
(li[
0
]())
print
(li[
2
]())
9
0
2
|
本文转自 beanxyz 51CTO博客,原文链接:http://blog.51cto.com/beanxyz/1861879,如需转载请自行联系原作者