名称空间
#什么是名称空间:
1、存放变量名与变量值绑定关系的地方
2、值存放在内存中,有一个内存地址,变量名指向地址
3、可是有很多变量名,可能分别指向不同的地址
4、所以需要一个空间来存放变量名指向的地址
# 名称空间的分类
1.内置名称空间
python语言内置的函数,也就是存放在python解释器中的
如:len() print()
2.全局名称空间
#在py文件中编写的代码运行产生的任何名字都会存到全局名称空间
usestr = '今天是3月17号' # 变量名usestr存入全局名称空间
def index(): # 函数名index存入全局名称空间
print(usestr)
3.局部名称空间
函数体代码运行产生的都是局部名称空间
def index():
name = 'zhangqiang' # name存入局部名称空间
# 存活周期
1.内置名称空间
#随着python解释器的关闭而关闭
关闭 销毁
2.全局名称空间
#随着python代码的运行结束而关闭
3.局部名称空间
#调用函数时创建,函数执行完毕时就销毁
名字的查找顺序
# 在查找名字的时候 一定要先搞清楚自己在哪个空间
1.如果在局部名称空间
局部名称空间 >>> 全局名称空间 >>> 内置名称空间
2.如果在全局名称空间
全局名称空间 >>> 内置名称空间
# 相当于大环套小环,内置名称空间是最大的环,局部名称空间是最小的环。
# 先在当前环里面找变量,找不到再去更大的环里找
'''局部名称空间之间如果不是嵌套关系 那么互不干涉!!!'''
def index1():
name = 'zhangqiang'
def index2():
age = 18
print(name) # 报错
index1()
index2()
作用域
# 作用域就是名称空间能够被调用的范围
'''为什么内置名称空间和全局名称空间都是全局有效'''
# 因为内置名称空间是python解释器自带的,我们无法修改或者编辑。
# 我们能够编辑最大的空间就是全局名称空间,我们所写的所有代码,都是在这层里面,不可能写到解释器里面。所有也是全局有效
内置名称空间
程序任意阶段任意位置均可使用(全局有效)
全局名称空间
程序任意阶段任意位置均可使用(全局有效)
局部名称空间
一般情况下只在各自局部名称空间中有效(局部有效)
global与nonlocal关键字
'''gloabl关键字:局部修改全局不可变类型'''
x = 111
def index():
# x = 222 # 并不是在修改全局的x 而是在局部名称空间中创建了一个新的x
# 如果想要在局部名称空间中修改全局名称空间中的名字 那么需要使用关键字申明
global x # 申明 修改的是全局x而不是产生新的x
x = 666
index()
print(x)
"""
如果想要在局部修改全局的不可变类型
需要提前加关键字global申明
如果想要在局部修改全局的可变类型
不需要加关键字global申明
"""
def index():
x = 111 # 在index的局部产生一个x=111
l1 = [11, 22, 33]
def f1():
# x = 222 # 在f1的局部产生一个x=222
# print(x)
# 局部名称空间嵌套 内层修改外层
# nonlocal x
# x = 333
l1.append(44)
f1()
print(x)
print(l1)
index()
"""
局部名称空间嵌套的情况下 内层如果想要修改外层
情况1数据是不可变类型
需要使用关键字nonlocal
情况2数据是可变类型
不需要使用关键字nonlocal
"""
函数名的多种用法
1.函数名可以当做变量名赋值 #相当于把具体的内存地址赋值过去
2.函数名还可以当成函数的实参 #内存地址也可以看成一个值
3.函数名还可以当做函数的返回值
4.函数名可以作为容器类型的元素
#根本原因就是函数名指向一个内存地址,然后内存地址也是一种数据,也可以当作变量值来使用
函数的嵌套
#在函数里面还可以定义函数,可以嵌套多层,执行需要被调用
name = "Alex"
def change_name():
name = "Alex2"
def change_name2():
name = "Alex3"
print("第3层打印", name)
change_name2() # 调用内层函数
# 输出
# 第3层打印 Alex3
print("第2层打印", name)
# 输出
# 第2层打印 Alex2
change_name()
print("最外层打印", name)
# 输出
# 最外层打印 Alex