1.作用域的介绍:#也叫名称空间
全局名称空间:创建的储存"变量名与值的关系"的空间叫做全局名称空间 #
局部名称空间:在函数的运行中开辟出来的空间叫做局部名称空间 #并非单指函数,例如在模块中,在类中的简单赋值操作都是局部作用域
内置名称空间:内置名称空间中存放了python解释器为我们储存的的函数,例如len(),print(),list()...都是python为我们创建好的内置函数。
python中的作用域分4中情况:
* L : local,局部作用域,函数中定义的变量
* E : enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的(闭包常见)
* G : globa,全局变量,是模块级别定义的变量
* B : bulit-in,系统固定模块里的变量,就是内置空间定义的 int(),print(),list()
加载变量的优先级顺序依次是:python内置作用域>当前模块中的全局(文件从上而下读取)>外层作用域>局部作用域
搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEJB
local 和 enciosing 是相对的,enclosing 变量相对上层来说也是 local
内置作用域:
x = int(2.9)# int就是内置作用域。(bulit-in)
全局作用域:
name = "mike" 变量赋值时的name就是全局变量(globa)
局部作用域:
def numbers():
number=10 # 函数内的number的赋值就是局部作用域(local)
嵌套的子级局部作用域:
def numbers():
number=10#局部作用域
def in_numbers():
in_number=20 # 子级局部作用域
搜索变量的优先级:
first1 = 2#全局变量
def numbers():
first1=10#局部变量
def in_numbers():
second = 20#嵌套的局部变量
print(first1)
in_numbers()
numbers()
#执行结果
10
#我定义了两个first1变量,一个是全局变量first1 = 2,一个是局部变量first1=10
#但是当我在使用嵌套的函数中打印变量名为first1时,打印的是10,而不是2,说明执行的结果为内部向外部一步步的进行搜索
#嵌套函数in_numbers首先向内部搜索,没有搜索到,然后开始向外部函数搜索,搜索到结果后立即返回
搜索变量时只能内部向外部进行搜索,而不能外层向内层搜索,除非先声明这个变量的归属。
作用域的产生:
在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的
例0:
>>>if 10>9:
>>> x=1
>>>print(x)#可正常执行
1
例1:
>>>def number():
>>> x=1
>>>print(x)
print(x)
NameError: name 'x' is not defined #python为我们指出了错误代码表示找不到x,因为我们知道,在全局环境中无法进行搜索局部环境的
变量的修改:
错误声明:
x=6
def f2():
print(x)#打印
x=5
f2()
#开始我认为是因为已经寻找了全局变量x的赋值,因为x已经加载至局部函数中,我企图在局部修改全局变量才会报错
#实验后发现应该是因为已经加载了内部函数,python发现了先引用后声明的行为而导致的报错
#测试方法为:当注释掉x=5时该程序可正常运行,寻找到了全局变量x=6,说明x=5和报错有着直接关系,但是还存在一种可能,当打印x时调用了全局变量x,下面的程序对全局变量进行修改,导致的报错。但是在代码print(x)后面加上代码return直接返回时,依旧会报错,说明了这个函数程序并非一步步执行的,而是先加载函数后执行。
def f2():
x+=1
#这里的错误就是因为局部变量想要修改全局变量导致的报错
global关键字:
使用global关键字时可以帮助你在局部中修改全局变量
count = 10
def outer():
global count#声明这是全局变量,可对全局变量进行修改
print(count)
count = 100
print(count)
outer()
#10
#100
# global 能少用就少用,因为会对全局变量做出修改,影响全局其他地方用这个全局变量
nonlocal关键字:
当在嵌套局部作用域上时,想要对局部作用域进行修改时,可以使用弄nonlocal关键字,global关键字只能在基于外部为全局变量是进行声明,而nonlocal可以在嵌套的局部中进行声明
def function1():
number = 200 #局部作用域
def in_function1():
nonlocal number#声明这是引用外部的局部作用域
number = 100#更改外部的局部作用域
print(number)
in_function1()
print(number)
function1()
#100
#100