名称空间:
1、什么是名称空间?
名称空间就是存放名字的地方,分为三种名称空间
1)内置名称空间:
# 因为是第一个被加载的名称空间,存放的是内置的名字,如print\input\len等
# 生命周期: 伴随解释器的启动而产生,随解释器的关闭则回收(销毁)
# 示例:
>>> print
<built-in function print> # built-in内建
2)全局名称空间:
# 因为是第二个被加载的名称空间,文件执行过程中存放的顶级的名字
# 生命周期: 伴随python文件的开始运行时产生,python文件运行结束则销毁(回收)
# 示例:
x = 10
def func():
x = 111
print(x)
3)局部名称空间:
# 存放的是函数的形参、函数内定义的名字
# 生命周期: 伴随调用函数时则产生,函数调用结束则销毁(回收)
# 示例:
def foo(x):
y=3
2、名称空间的加载顺序:
# python解释器先启动,因而首先加载的是:内置名称空间
# 执行test.py文件,然后以文件为基础,加载全局名称空间
# 在执行文件的过程中如果调用函数,则临时产生局部名称空间
# 名称空间的加载顺序:内置名称空间->全局名称空间->局部名称空间
4、名字的查找优先级:
# 从当前位置往外查找:
# 如果当前是在局部:局部名称空间->全局名称空间->内置名称空间
# 如果当前是在全局:全局名称空间->内置名称空间
# 示范1:
def func():
len = 222
func()
print(len) # len=222
# 名称空间可以理解为一层套一层的关系,问题是嵌套关系是在函数定义阶段生成的,还是在函数调用阶段生成的?
# 定义阶段生成的!!!
x = 111
def foo():
print(x)
def bar(f):
x=222
f()
bar(foo)
# 一个非常重要的结论:名称空间的嵌套关系是函数定义阶段(即扫描语法时)就固定死的,与函数的调用位置无关
x = 111
def func():
print(x)
x=2222
func()
# 练习
'''
# x=0
def f1():
# x=1
def f2():
# x=2
print(x)
f2()
f1()
'''
len = 111
def f1():
len=2222
def f2():
len=3333
f1()
f2()
5、作用域
# 按照名字作用范围的不同可以将三个名称空间划分为两个区域:
# 全局范围/全局作用域:内置名称空间+全局名称空间
特点:全局存活,全局有效
# 局部范围/局部作用域:局部名称空间
特点:临时存活,局部有效
# 可以调用内建函数local()和globals()来分别查看局部作用域和全局作用域的名字,查看的结果都是字典格式。在全局作用域查看到的locals()的结果等于globals()
案例一:
x = 10
def func(x): # x = 值10的内存地址
# x = 值10的内存地址
x = 20
func(x) # func(值10的内存地址)
print(x)
案例二:
x = [11,22,33]
def func(x): # x = 列表[11,22,33]的内存地址
# x = 列表[11,22,33]的内存地址
# x=444444444444
x[0] = 66666
func(x) # func(列表[11,22,33]的内存地址)
print(x)
案例三:
x = [11,22,33]
def func():
x[0] = 66666
func()
print(x)
案例四:global
x = 10
def func():
global x
x=22
func()
print(x)
案例五:nonlocal
# nonlocal x会从当前函数的外层函数开始一层层去查。找名字x,若是一直到最外层函数都找不到,则会报错!!!nonlocal不会查全局名称空间!!!
x = 10
def f1():
x=111
def f2():
nonlocal x
x=222
f2()
print(x)
f1()
print(x) # x = 222 ,x = 10