今天的学习内容有命名关键字参数、函数对象、函数的嵌套、函数的名称空间以及作用域。
关键字参数
举个栗子 def func(x,y=1,*args,z=3,m,**kwargs): print(x,y) print(args) print(z,m) print(kwargs) func(1,2,1,3,4,5,6,7,8,9,z=69,m=999,o=988989,l=898989)
输出的结果为
在这个例子中我们可以看到,z和m好像是把z这个默认值参数放在了m这个位置参数之前,程序应该报错,然而并没用,其实z和m并不是默认值参数和位置参数,而是命名关键字参数。
命名关键字参数:实在函数定义的阶段,写在*和**之间的形参,它的特点是只能用关键字为其传值。
函数对象
1.函数名是可以被传递的
def func(): print('from func') print(func) print(id(func)) f = func func() print(f) f() # 其实指向的也是函数func指向函数体代码的内存地址
输出结果
2.函数名可以被当做参数传递给其它函数
def func(): print('from func') def index(args): print(args) args() # 相当于func() print('from index') index(func)
运行结果
3.函数名可以被当做函数的返回值
def index(): print('index') def func(): print('func') return index res = func() print(res) res()
运行结果
4.函数名可以被当做容器类型的参数
def func(): print('func') print(func()) l = [1,2,func,func()] print(l)
运行过程: 运行结果:
函数的嵌套
函数嵌套作用是在函数内部调用其他的函数,这样可以将复杂的逻辑简单化。
两个数比大小 def my_max(x,y): if x > y: return x return y 四个数比大小 def my_max4(a,b,c,d): res1 = my_max(a,b) # 先用a,b比较 res2 = my_max(res1,c) # 再用c和上面的结果比较 res3 = my_max(res2,d) # 再用d和上面的结果比较 return res3 print(my_max4(1,2,10,4))
函数的名称空间
名称空间是什么?放名字的地方,就是存放变量名与变量值的内存地址绑定关系的地方。
名称空间的分类分为三种:内置名称空间、全局名称空间、局部名称空间。
内置名称空间:python解释器提前给你定义好的名字(已经存放到内置名称空间中了,如len、 max、min)
全局名称空间:文件级别的代码
x = if 1 ==1 : y = 2 print(y) while True: z = 3 x,y,z都会放到全局名称空间 if for while 无论嵌套多少层 它们内部所创建的名字都是全局名称空间的
局部名称空间:函数体内创建的名字都属于局部名称空间
函数名称空间的生命周期:
内置名称空间:只要python解释器已启动立马创建 关闭python解释器的时候内置名称空间自动销毁
全局名称空间:只要你右键运行py文件会自动创建 py文件程序运行结束自动销毁
局部名称空间:函数被调用的时候自动创建 函数指向结束立即销毁(动态创建动态销毁)
函数名称空间的加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
名称的查找顺序
需要先确定你当前在哪(大前提)
1.站在全局: 全局 >>> 内置
2.站在局部: 局部 >>> 全局 >>> 内置
len='全局名称空间说我' def func(): len ='局部名称空间说我' print(len) print(len) # 全局名称空间说我 func() # 局部名称空间说我
函数在定义阶段查找名字的顺序就已经固定了 不会因为函数的调用位置变化而改变
输出是111还是222? x=111 def outer(): def inner(): print('from inner',x) return inner f=outer() x=222 f() >>>:from inner 222
输出的是111还是333? x=111 def outer(): def inner(): print('from inner',x) return inner f=outer() def func(): x=333 f() func() >>>:from inner 111
x=111 def outer(): def inner(): print('from inner',x) # x的定义在def inner内,但在调用的时候还没有执行到x定义,所以会报错 x=666666 return f=outer() f()
作用域
可以局部修改局部的变量,也可以局部修改全局的变量,关键字是global和nonlocal
x=[] # 可变数据类型 username ='jason' def func(): x.append('嘿嘿嘿') func() print(x) >>>:['嘿嘿嘿']
#global在局部修改全局的不可变数据类型 x=1 # 不可变类型 username ='jason' def func(): global x,username # 修改全局变量,而不是创建局部名称空间 x=999 username='egon' func() print(x) # 999 print(username) # egon
#nonlocal 局部修改局部 def func(): x=1 def index(): nonlocal x x=2 index() print(x) func()
global:局部修改全局 如果想修改多个 逗号隔开
nonlocal:局部修局部 如果想修改多个 逗号隔开