1. 名称空间
1.1 概念
名称空间是存放变量名与变量值映射关系的地方
1.2 分类
1.2.1 内置名称空间
Python解释器运行而产生的名称空间,如def、if、else、len
Python解释器运行---产生
Python解释器关闭---释放
1.2.2 全局名称空间
在python文件中编写的代码运行产生的名字都会存到全局名称空间(函数体代码之外的)
name = 'LeoMessi' # 变量名name存入全局名称空间def login(): # 函数名login存入全局名称空间passif True:a = 111 # 变量名a存入全局名称空间
for i in range(10): # 变量名i存入全局名称空间 pass
while True:b = 222 # 变量名b存入全局名称空间
python文件开始运行 产生
python文件运行结束 释放
1.2.3 局部名称空间
函数体代码运行产生的都是局部名称空间
def register():name = 'ronaldo' # name存入局部名称空间
函数体代码开始运行 产生
函数体代码运行结束 释放
1.3 名称空间的查找顺序
在查找名字的时候,一定要先搞清楚当前在哪个空间
1. 如果在局部名称空间
局部名称空间————> 全局名称空间————> 内置名称空间
2. 如果在全局名称空间
全局名称空间————> 内置名称空间
(只能向外层不能向里层)
3.代码执行顺序
# 局部名称空间之间如果不是嵌套关系,那么互不干涉
def f1():name = 'LeoMessi'
def f2():age = 35print(name) # 报错not defined
f1()
f2()
2. 作用域
2.1 概念
作用域就是名称空间能够作用的范围,即变量名和变量值可以被访问的范围(变量名定义的位置和可以查找的位置)
2.2 分类
内置作用域 Built-in
Built-in(内置):解释器内置的变量,比如int, str等。
作用范围:所有模块(文件)
Python中没有块级作用域。
块级作用域:代码块中的变量,比如if、while、for后面的代码
程序任意阶段、任意位置均可使用(全局有效)
全局作用域 Global
Global(全局):一般模块文件顶层声明的变量具有全局作用域,从外部来看,模块的全局变量就是一个模块对象的属性,仅限于单个模块文件中。
作用范围:当前模块(文件)
程序任意阶段、任意位置均可使用(全局有效)
局部作用域 Local
Local(局部变量):暂时的存在,依赖于创建该局部作用域的函数。
函数存在,则局部变量存在;函数不存在,则局部变量不存在。
作用范围:当前整个函数体范围
一般情况下,只在各自局部名称空间中有效(局部有效)
内嵌作用域 Enclosed
Enclosed(嵌套):一般是在函数中嵌套函数的时候,外层函数的变量作用域。
作用范围:闭包函数
2.3 作用域举例
内置作用域举例:
内建作用域里面提前加载好的 如os
import os
全局作用域举例:
自己在文件中定义的变量
num = 123
局部作用域与内嵌作用域举例:
age = 18
# 局部作用域:定义在函数或者类内部的所有变量
# 内嵌作用域:在函数中嵌套函数的时候,外层函数的变量作用域。
def student():age = 28 # 这里的age对student函数是局部作用域,对inner函数是内嵌作用域print(f" student my age is {age}")def inner():age = 38 # 这里的age为inner函数的局部作用域print(f"inner my age is {age}")inner()student()
print(f"global my age is {age}")
作用域的加载顺序:内置 -- 全局 -- 外层 -- 里层
查找循序 : 里层 -- 外层 -- 全局 -- 内置
查找顺序遵循一个规则 LEGB 规则
L ---> local 局部的局部 最里层的函数
E ---> enclosed 内嵌,相对里层嵌套函数的外层
G ---> global 全局
B ---> built-in 内建
2.4 作用域声明
def func():
# 使用关键字来提 高当前变量的级别
# 局部修改全局不可变数据类型需要使用 global 提高当前作用域级别
global age
age = 19
age_ = age
print(f"func my age is {age}")
print(f"func my age_ is {age_}")
user_dict["age"] = 999
def inner():
# 提高内嵌函数作用域的变量级别
nonlocal age_ # no binding for nonlocal 'age' found
age_ = 38
print(f"inner my age_ is {age_}")
user_dict["age"] = 888
inner()
print(f"func my age_ is {age_}")
func()
print(f"global my age is {age}")
print(user_dict["age"])
# 字典是可变数据类型 ,大家对于修改字典的时候都是修改的同一块内容空间地址上面的值
# 【总结】
# 【1】名称空间就是存放变量名和变量值映射关系的地方 内建 全局 局部
# 【2】作用域就是变量名和变量值映射关系存放的范围 内建 全局 局部 内嵌
# 【3】如果局部修改全局不可变数据类型 用 global 提高当前作用域级别
# 如果是内嵌修改局部不可变数据类型 用nonlocal 提高作用域级别
# 内嵌作用域无法修改全局作用域中的不可变数据类型