瀋凣
V1
2022/03/03阅读:86主题:极简黑
python笔记37
Python day37
1. 函数
1.5 作用域
所谓作用域,就是指变量可以被访问的范围。通常,一个变量的作用域总是由它在代码中被赋值的位置决定的。
1.5.1 局部作用域
如果一个变量定义的位置是在函数内部,那么这个变量的作用域就仅限于该函数中,我们称之为局部变量。
>>> def myfunc():
... x = 520 #在函数内部定义的变量,局部变量
... print(x)
...
>>> myfunc()
520
-
尝试在函数外访问局部变量x
>>> print(x) #报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
1.5.2 全局作用域
如果是在任何函数的外部定义一个变量,那么这个变量的作用域就是全局的,我们称之为全局变量。
>>> x = 886
>>> def myfunc():
... print(x)
...
>>> myfunc()
886 #函数可以访问到外部的变量
当函数内外存在同名变量时,会发生什么呢?
>>> x = 886
>>> def myfunc():
... x = 520
... print(x)
...
>>> myfunc()
520
>>> print(x)
886
我们发现,局部变量会覆盖同名的全局变量。
其实,上例中的全局变量x
和局部变量x
并不是同一个变量,只是由于作用域的不同,两个变量同名不同样。
-
当函数内没有同名局部变量时,函数内访问到的x就是全局变量x
>>> x = 886
>>> id(x)
515121817008
>>> def myfunc():
... print(id(x))
...
>>> myfunc()
515121817008
-
当函数内存在同名变量时,函数内访问到的x就是和全局变量完全不同的另一个变量
>>> def myfunc():
... x = 886
... print(id(x))
...
>>> myfunc()
515121817520
由此可知,全局变量可以在函数的内部被访问到,但是却无法在函数的内部修改它的值。因为一旦试图在函数内进行赋值操作,Python就会立刻创建一个同名的局部变量进行覆盖。
1.5.3 global
语句
那么是否就无法在函数内部修改全局变量了呢?
并不是,我们可以通过global
关键字来实现在函数内部修改全局变量。
>>> def myfunc():
... global x #先用global关键字声明
... #注意:这里不能写成 global x = 520 这种写法
... x = 520
... print(x)
...
>>> myfunc()
520
>>> print(x)
520
1.5.4 嵌套函数及其变量作用域
函数也可实现嵌套操作。
-
自定义一个嵌套函数
>>> def myfunA():
... x = 520
... def myfunB():
... x = 886
... print('in myfunB(),x = ',x)
... print('in myfunA(),x = ',x)
... myfunB()
...
-
在函数外部,无法调用内层的嵌套函数,内层的函数只能在函数内部被调用
>>> myfunB()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'myfunB' is not defined
-
调用外层函数
>>> myfunA()
in myfunA(),x = 520
in myfunB(),x = 886
从打印结果可知,内层函数可以访问到外层函数的变量,但是无法修改它。
1.5.5 nonlocal
语句
如果要修改嵌套作用域(外层非全局作用域)中的变量则需要 nonlocal
关键字。
>>> def myfunA():
... x = 520
... def myfunB():
... nonlocal x
... x = 886
... print('in myfunB(),x = ',x)
... myfunB()
... print('in myfunA(),x = ',x)
...
>>> myfunA()
in myfunB(),x = 886
in myfunA(),x = 886
1.5.6 LEGB
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有4种,分别是:
-
L(Local):最内层,包含局部变量,比如一个函数/方法内部。 -
E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。 -
G(Global):当前脚本的最外层,比如当前模块的全局变量。 -
B(Built-in): 包含了内建的变量/关键字等,最后被搜索。
规则顺序: L → E → G → B。
在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。

>>> str = 'kill str'
>>> str(520)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable

作者介绍
瀋凣
V1