函数对象与闭包函数
一.global与nonlocal
global关键字:
若要在函数内修改全局名称空间中的"名字"的值,当值为不可变类型时,则需要添加global关键字。若值为可变类型则不需要
# 修改a的值
a = 123
def index():
global a # 声明修改的是全局名称空间中的a,而不是产生新的a
a = 666
index()
print(a)
# 666
nonlocal:
若嵌套多层函数时,内层函数想要修改外层函数局部名称空间中‘名字’的值,可以使用nonlocal关键字(非全局)
a = 10
def func():
a = 1 # 局部变量a
def func1():
nonlocal a # 声明修改的时外层局部名称空间的a 而不是产生新的a
a = 2 # 将值2重新赋值给a
func1() # 调用func1
print(a) # 此时func()函数代码体中的变量a被func1()重新赋值2
func() # 调用函数func
# 2
print(a) # 这是全局空间的a
# 10
注意:
使用global关键字修饰的变量之前可以并不存在,而使用nonlocal关键字修饰的变量在嵌套作用域中必须已经存在,否则会报错。
二.函数名的多种用法
函数名其实绑定的也是一块内层地址,只不过该地址里面存放的不是数据值而是一段代码,函数名加括号就会找到该代码并执行
1.可以当做变量名赋值
def index():
print('哈哈哈')
res = index # 将index赋值给res
res() # 调用index函数 其实就等于index()
# 哈哈哈
2.可以当做函数的参数
def index():
print('from index')
def func(a):
print(a)
a()
func(index) # 此时就是将函数index作为实参和形参a对应
# from index
3.可以当做函数的返回值
def index():
print('from index')
def func():
print('from func')
return index
res = func()
# 调用函数func 先执行print('from func') 然后返回值index 此时返回的是index函数 然后执行print('from index')
print(res) # 等同于prin(index)
res()
# from func
# 打印res内存地址
# from index
-------------------------------------------------------------------
def index():
print('from index') # 先执行
def func():
print('from func')
return func # 返回func
res = index() # 此时index()就是内层函数func()
print(res)
res()
# from index
# 打印res内存地址
# from func
4.可以当做容器类型的数据
def register():
print('注册功能')
def login():
print('登录功能')
def withdraw():
print('提现功能')
def transfer():
print('转账功能')
def shopping():
print('购物功能')
# 定义功能编号与功能的对应关系
func_dict = {
'1': register,
'2': login,
'3': withdraw,
'4': transfer,
'5': shopping
}
while Ture:
print("""
1.注册功能
2.登录功能
3.提现功能
4.转账功能
5.购物功能
""")
choice = input('输入功能编号>>>:').strip()
if choice in func_dict:
func_name = func_dict.get(choice)
func_name()
else:
print('功能编号不存在')
if choice == '1':
register()
elif choice == '2':
login()
elif choice == '3':
withdraw()
elif choice == '4':
transfer()
elif choice == '5':
shopping()
else:
print('没有该功能')
三.闭包函数
概念:
定义在函数内部的函数,并且用到了外部函数名称空间中的名字
1.定义在函数内部
2.用到外部函数名称空间中的名字
def index():
name = 'jason'
def innder():
print(name)
闭包函数实际应用>>>:是另外一种给函数体代码传参的方式!!!
给函数体代码传参的方式1:代码里面缺什么变量名形参里面就补什么变量名
def register(name, age):
print(f"""
姓名:{name}
年龄:{age}
""")
register('jason', 18)
给函数体代码传参的方式2:闭包函数
def outer(name, age):
# name = 'jason'
# age = 18
def register():
print(f"""
姓名:{name}
年龄:{age}
""")
return register
res = outer('jason', 18)
res()
res()
res = outer('kevin', 28)
res()
res()