1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
1 、作用域
如果一个变量在 def 内赋值,他被定位在这个函数内
如果一个变量在一个嵌套的 def 中赋值,对于嵌套的函数来说,它非本地的
如果在 def 之外赋值,他就是整个文件
2 、在交互式模式下,其实是在一个名为__main__的模板内。
3 、一个函数的内部的任何类型的赋值都会把一个名称划定为本地的。这包括 = 语句, import 中的模板名称, def 中的函数名称,函数参数名称等。如果在一个 def 中以任意方式赋值的名称,他都将对于该函数是本地的。
注意:原处改变对象并不会把变量划分为本地变量。
4 、变量名解析:LEGB原则
1 变量名引用分为三个作用域进行查找:首先是本地,然后是函数内(如果有的话),之后是全局的,最后是内置的
2 默认情况下,变量名赋值会创建或者改变本地变量
3 全局声明和非本地声明将赋值的变量名映射到模板文件的内部作用域。
4 当在函数中使用未认证的变量名时,python搜索 4 个作用域(本地作用域,之后是上一层次中的 def 或者 lambda 的本地作用域,之后是全局,最后是内置的)并且在第一处能找到这个变量的地方停下来,如果变量名在这个过程中没有找到则会报错。
5 、内置作用域
内置作用域仅仅是一个名为builtins内置模板,要在 import
builtins才能使用
import
builtins
print ( dir (builtins))
6 、全局变量
全局变量是位于模板文件内部的顶层的变量名
全局变量如果在函数内部被赋值的话,必须经过声明
全局变量在函数的内部不经过声明也可以被引用
7 、工厂函数(闭合函数)
一个能够记住嵌套作用变量的函数
例如:
def
maker(N):
def
action(X):
return
X * * N
return
action
f =
maker( 2 )
print (f( 2 )) #输出9
8 、这个例子需要思考:
def
f():
a =
[]
for
i in
range ( 5 ):
a.append( lambda
x ;i * * x)
return
a
t =
f()
print (t[ 0 ]( 2 )) #输出16
print (t[ 1 ]( 2 ),t[ 2 ]( 2 )) #输出16,16
解释:因为 for 循环结束后,i的值是 4 ,记住这个i = 4 ,所以当调用时,x的值才被传进来。
解决办法是使用默认参数:
def
f():
a =
[]
for
i in
range ( 5 ):
a.append( lambda
x,i = i ;i * * x) #这里的i等于这次循环时的i
return
a
t =
f()
print (t[ 0 ]( 2 )) #输出0
print (t[ 1 ]( 2 ),t[ 2 ]( 2 )) #输出2,4
9 、nonlocal使用举例
def
tester(start):
state =
start
def
nested(label):
nonlocal state #如果没有这个,下面的是state+=1不行的
print (label,state)
state + = 1
return
nested
|