1. 函数作用域
即一块文本区域,是变量或函数访问的时候查找名称的范围空间。
1.1. 全局变量&局部变量
【局部变量】Global
定义在函数内部的变量(包含函数参与)
【全局变量】Local
定义在函数外部,模块内部(当前.py)的变量
#Example_1
#global_local.py
v=100 #<---全局变量
def test():
v=200 #<---局部变量
print(v)
test() # 200
print(v) #100
在Example_1中,为何“同一个”v通过fn()和print输出结果不同呢?
这是因为通过调用test()函数输出的v是在局部的变量,所以会输出在函数内部作用域的200,而print中输出的是在全局存储的100。
【注意】
不同函数内的变量是存在于不同的局部的!
1.2. Python作用域的4个分类
1、局部作用域(函数内) Local
2、外部嵌套函数作用域 Enclosing function locals E
3、函数定义所在模块(文件)的作用域 Global(module) G
4、Python内置模块的作用域 Built-in(Python)B
#Example_2
#fourClass.py
v=100 # 全局作用域 G
def test1():
v=200 # 外部嵌套函数作用域 E
print("test1.v=", v)
def test2():
v=300 #
print("test2.v=", v) # 局部作用域 L
test2()
test1() # 200
print(v) #100
#Example_3
print(__doc__) #__doc__是内建作用域的变量
1.3. 变量名的查找规则
在访问变量时,先查找本地变量,然后是包裹此函数的外部函数的函数内部的变量,之后是全局变量,最后是内置变量。若都没有,则报错。
L --> E --> G --> B
1.4. 全局声明 global
在1.1.的Example_1中,若想要函数test调用后输出的外部一样,则需要将其声明为全局变量,如下:
v=100 #<---全局变量
def test():
global v #声明全局变量v
v=200 #<---局部变量
print(v)
test() # 200
print(v) #100
【global语句作用】
告诉解释器,global语句声明的一个或多个变量,这些变量的作用域为模块级的作用域,也称作全局变量。
对全局声明(global)的变量赋值将映射到模块文件的内部作用域。
【语法】
global 变量名1, 变量名2,。。。
【注意】
定义的全局变量不能出现在函数参数中!
#CounterExample_1
v=100
def counterTest(v):
global v #Error! v出现在参数列表里
print(v)
counterTest(200)
【说明】
1、全局变量如果要在函数内部被赋值,则必须经过全局声明,否则被认为是局部变量;
2、全局变量在函数内部不经过声明就可以直接读取访问(前提是变量已经存在),但是只能读取不能写入;
3、不能先声明局部变量,在用global声明为全局变量,此做法不符合语法规则;
4、global变量列表里的变量名不能出现在此作用域的参数列表里,for循环控制目标、类定义、函数定义及import导入名字中。
1.5. 函数嵌套
函数嵌套是指一个函数里用def语句来创建其他函数的情况。
#Example_4
def fn_outer():
print("外部函数被调用")
def fn_inner():
print("内部函数fn_inner被调用")
fn_inner()
fn_inner()
print("外部函数调用结束")
fn_outer()
#fn_inner() #错的,内嵌函数只存在于函数内部
【nonlocal语句】
【作用】
告诉解释器,nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。
【语法】
nonlocal 变量名1, 变量名2,…
#Example_5
var = 100
def outter():
var = 200
def inner():
nonlocal var # 指定var为外层嵌套函数作用域--就近使用
# global var
var +=1 #此行会出错
pirnt("inner.var=", var)
inner()
print("outter.var=", var)
outter()
【globals() / locals() 函数】
globals() 返回当前全局作用域内变量的字典
locals() 返回当前局部作用域内变量的字典
#Example_6
a=1
b=2
def fn(c, d):
e=300
print("locals 返回:", locals()) #{'e':300, 'c':100, 'd':200}
print("globals返回:", globals()) #{'a':1, 'b':2, 'fn':<xxxxx>}
fn(100, 200)
在Example_6中,globals返回的值中有'fn':<xxxx>
是因为——Python中函数也是一种变量,所以fn同样也会返回,其中<xxxx>
则是代码段的虚拟地址。