函数对象、函数的嵌套调用与定义、名称空间、作用域、闭包函数
昨日补充内容:
定义函数的三种方式:
1.空函数:可以快速的帮助自己构建项目框架,使项目架构清晰明了
def func(): pass
这种方式应用频率非常高
比如购物车功能:
def register(): passdef login(): passdef pay(): pass
2.无参函数:
def func(): print('from func')
3.有参函数:
def func(x,y,*args,**kwargs) print(x,y,*args,**kwargs)
命名关键字参数:在函数定义阶段,写在*与** 可变长参数之间的形参
特点:
- 1.在给命名关键字参数传值的时候,只能用关键字为其传值
- 2.在定义阶段,给人的感觉好像是z是默认值参数,放在了m这个位置参数之前,且应该报错,其实z和m都是命名关键字参数,而不是默认值参数和位置参数
def func(x,y=1,*args,z=3,m,**kwargs) print(x,y) # 1 2 print(args) # (3,4,5,6,7,8) print(z,m) # z=88,m=99 print(kwargs) # {'0':11,'s':22}func(1,2,3,4,5,6,7,8,z=88,m=99,o=11,s=22)
函数对象
函数是第一类对象:函数名指向的值可以被当作参数传递
特点:
1.函数名可以被传递
name = 'jason'x = nameprint(x) # 'jason'def func(): print('from func') print(func)f = funcfunc()print(f)f() # f其实指向的也是 函数func指向的 函数体代码的内存地址
2.函数名可以被当作参数传递给其他函数
def func(): print('from func') def index(args): print(args)args()print('from index')index(1)index(func)
3.函数名可以被当作函数的返回值
def index(): print('from index')def func(): print('from func') 若return 11res = func()print(res) # 结果为 11res() 若return indexres1 = func()print(res1) #res1()
4.函数名可以被当作容器类型的参数
def func();print('func') #print(func()) # Nonel = [1,2,func,func()]print(l) # [1,2, ,None]
ATM+购物车项目
需求:循环打印项目功能,供用户选择,用户选择谁就执行谁
def register(): username = input('username>>>:').strip() pwd = input('password>>>:').strip() print(username,pwd) print('register...')def login(): print('login...')def transfer(): print('transfer...')def shopping(): print('shopping...')def pay(): print('pay...')msg = '''''' 1 注册 2 登陆 3 转账 4 购物 5 支付''''''func_dict = { '1':register, '2':login, '3':transfer, '4':shopping, '5':pay}while True: print(msg) choice = input('请选择你想要执行的功能>>>:').strip() if choice in func_dict: func_dict.get(choice)() '''等价于函数名()''' else: print('功能暂时没有')
函数的嵌套调用
在函数内部调用其它函数
def index(): print('index')def func(): index() print('func')func() # 结果为 index func
def index(): func() print('index')def func(): print('func')index() # 结果为 func index
比较大小:
def my_max(x,y): if x > y: return x return ydef my_max4(a,b,c,d): res1 = my_max(a,b) # 返回值为a,b中大的值 res2 = my_max(res1,c) res3 = my_max(res2,d) return res3print(my_max4(1,2,10,4)) # 结果为10
函数的嵌套定义(重要)
def outer(): x = 1 print('outer')def inner(): print('inner') print(x) # 报错 print(inner) # 报错outer() # 结果为outer
def outer(): x = 1 print('outer')def inner(): print('inner')print(inner) #inner()
def outer(): x = 1 print('outer') # 结果为outer def inner(): print('inner') return innerres = outer()print(res) #.inner at 内存地址> res() # 结果为inner
函数的嵌套定义及应用场景
'''
写一个函数
该函数用户可以通过传参的不同来控制函数执行不同的代码
'''
def all_func(type): def register(): print('register') def login(): print('login') def pay(): print('pay') if type == '1': register() elif type == '2': login() elif type == '3': pay()all_func('1')all_func('2')all_func('3')
名称空间是什么?(重要)
名称空间就是放名字的地方
详细解释:存放的是变量名与变量值的内存地址的绑定关系的地方
要想访问一个变量的值,就必须先去名称空间中拿到对应的名字,才能够访问变量的值
名称空间的分类:
- 1.内置名称空间:python解释器提前给你定义好的名字(事先已经存放到内置名称空间中了);比如(len、max、min等)
- 2.全局名称空间:文件级别的代码,具体如下
x = 1if l == 1: y = 2 print(y)while True: z = 3for i in [1,2,3]: print(i)
如上代码中x,y,z都会放到全局名称空间,if、while、for无论嵌套多少层,它们内部所创建的名字都是全局名称空间的
- 3.局部名称空间:函数体内创建的名字都属于局部名称空间
名称空间的生命周期:
- 内置名称空间:只要python解释器一启动就立马创建;关闭python解释器时,就自动销毁
- 全局名称空间:只要你右键运行py文件,会自动创建,py文件运行结束时自动销毁
- 局部名称空间:函数被调用时自动创建,函数执行结束后立即销毁(动态创建、动态销毁)
名称空间的查找顺序(重要):
1.需要先确定你当前在哪(大前提)
- 1):站在全局:全局>>>内置
- 2):站在局部:局部>>>全局>>>内置
2.例题
函数在定义阶段查找名字的顺序就已经固定了,不会因为函数的调用位置变化而改变
len = '我是全局名称空间的len'def func(): len = '我是局部名称空间的len' print(len)print(len) # 这里是在全局
def func(): len = '我是局部名称空间的len' print(len)print(len) # 这里是内置len, built-in function len
len = '我是全局名称空间的len'def func(): len = '我是局部名称空间的len' print(len)func() # 这里是局部名称空间的len
len = '我是全局名称空间的len'def func(): print(len)func() # 这里是全局名称空间
作用域
全局作用域:
- 全局有效:内置名称空间,全局名称空间
局部作用域:
- 局部有效:局部名称空间
global、nonlocal
1.global在局部修改全局的变量
x =1def func(): x = 2func()print(x) # 结果为1
x = [] # 因为列表是可变类型,所以能够从局部修改全局 def func(): x.append('嘿嘿嘿')func()print(x)
# global 可以在局部修改全局的不可变数据类型x = 1def func(): global x # 修改全局变量,而不是创建局部名称空间 x = 2func()print(x) # 结果为2
2.nonlocal 局部修改局部
def func(): x = 1def index(): x = 2print(x)func() # 结果为1
def func():x = 1 def index(): nonlocal x x = 2 print(x)func() # 结果为2
'''
global:局部修改全局,如果想修改多个,逗号隔开
nonlocal:局部修改局部,如果想修改多个,逗号隔开