今日内容总结
一、名称空间
二、名字的查找顺序
三、作用域
四、global和nonlocal关键字
五、函数名的多种用法
六、函数的嵌套

一、名称空间
1、名称空间含义
指存放变量名与变量值绑定关系的地方,相当于它存在的这个空间,和我们平时的民政局、警察局等
2、名称空间的分类
2.1 内置名称空间
python解释器提前已经定义好的,现在直接拿过来用就可以了
len() print() open() max()
2.2 全局名称空间
在py文件中编写的代码运行产生的名字都会存到全局名称空间
name = 'owen' # 变量名name存入全局名称
age = 28 # 变量名age存入全局名称
def index(): # 函数名index存入全局名称空间
if True:
a = 11 # 变量名a存入全局名称空间
for i in range(10): # 变量名i存入全局名称空间
2.3 局部名称空间
函数体代码运行产生的都是局部名称空间
def index():
name = 'owen' # name存入局部名称空间
3、存活周期
3.1 内置名称空间
python解释器运行 —— 产生
python解释器关闭 —— 销毁
3.2 全局名称空间
py文件开始运行 —— 产生
py文件运行结束 —— 销毁
3.3 局部名称空间
函数体代码开始运行 —— 产生
函数体代码结束运行 —— 销毁
二、名字的查找顺序
"""
名称空间是用来存放名字与值绑定关系的地方,那我们找这个名字,去哪找?
"""
# 在我们查找这个名字的时候,一定要先搞清楚自己要在哪找,在那个空间
1. 当这个名字在局部名称空间
局部名称空间 >>> 全局名称空间 >>> 内置名称空间
2. 当这个名字在全局名称空间
全局名称空间 >>> 内置名称空间
# 当三个名称空间中都有这个相同的名字
len = '我是全局名称空间中的len1'
def index():
len = '我是局部名称空间中的len2'
print(len)
index() # 调用函数,函数体就会执行,就会产生局部空间
print(len)
# 我是局部名称空间中的len2
# 我是全局名称空间中的len1
x = 'aaa'
def f1():
x = 'bbb'
def f2():
x = 'ccc'
def f3():
x = 'ddd'
print(x) # 检测语法时,发现f3的局部名称空间将会有x,所有查找的时候,就在f3的局部名称空间里找
f3()
f2()
f1() # ddd
"""局部名称空间之间如果不是嵌套关系,则他们之间互不干涉"""
def index1():
name = 'owen'
def index2():
age = 20
print(name) # 在函数名index局部名称空间中没有name,所有会发生报错
index1()
index2()
三、作用域
# 作用域顾名思义就是名称空间能够作用的范围
内置名称空间(解释器自带的)
程序任意阶段任意位置都可以使用(全局有效)
全局名称空间
程序任意阶段任意位置都可以使用(全局有效)
局部名称空间
只能在各自局部使用(局部有效)
四 、global 与nonlocal关键字
'''global关键字:局部修改全局不可变类型 '''
x = 111
def index():
# x = 222 # 这个并不是修改全局的x ,而是在局部名称空间中创建一个新的x
# 如果想要在局部名称空间中修改全局名称空间中的名字,就需要使用关键字声明
global x # 修改的是全局x而不是产生新的x
x = 999
index()
print(x) # 999
l1 = [111, 222, 333]
def index():
l1.append(444)
index()
print(l1) # [111, 222, 333, 444]
# 如果在局部修改全局的不可变类型,需要提前加关键字global声明
# 如果在局部修改全局的可变类型,不需要提前使用global声明
nonlocal使用
def index():
x = 666
l1 = [111, 222, 333]
def f1():
# x = 22 # 在f1的局部产生一个x = 22
# print(x)
# 局部名称空间嵌套 ,内层修改外层
nonlocal x
x = 123
l1.append(444)
f1()
print(x)
print(l1)
index() # 123
# [111, 222, 333, 444]
"""
局部名称空间嵌套的情况下,内层如果想要修改外层
情况1当数据是不可变类型时
需要使用关键字nonlocal
情况2当数据是可变类型时
不需要使用关键字nonlocal
"""
五、函数名的多种用法
1 、函数名可以当作变量名赋值
def index ():
print('form function index')
print(index)
res = index # 让res 也指向函数体代码
print(res)
res()
# <function index at 0x000002209A7BD430>
# <function index at 0x000002209A7BD430>
# form function index
2 、函数名还可以当成函数的实参
def index():
print('from index')
def func(a):
print('from func')
print(a)
a()
func(index)
# from func
# <function index at 0x000001E7099BD430>
# from index
3 、函数名还可以当成函数的返回值
def func():
print('from func')
return index # 将函数名当作返回值
def index():
print('from index')
res = func() # res接受函数名
print(res) # 指向index函数的内存地址
res()
# from func
# <function index at 0x000001C75E318940>
# from index
4 、函数名可以作为容器类型的元素
容器类型:内部可以存档多个元素的数据类型:列表、元组、字典
def index():
print('from index')
l1 = [11, 22, 33, 44, index]
print(l1)
l1[-1]()
# [11, 22, 33, 44, <function index at 0x000001A62FE7D430>]
# from index
六 、函数的嵌套
# 函数的嵌套调用
def my_max(a, b): # 返回最大值
if a > b:
return a
return b
print(my_max(100,999)) # 999
def many_max(a, b, c, d):
res = my_max(a, b)
res1 = my_max(res, c)
res2 = my_max(res1, d)
#这个就是两个对比,依次对比
def all_func(cmd):
def register():
print('注册功能')
def login():
print('登录功能')
def transfer():
print('转账功能')
if cmd == '1':
register()
elif cmd == '2':
login()
elif cmd == '3':
transfer()
else:
print('请输入正确的功能编号')
all_func('1') # 注册功能
