进阶函数
一、函数对象
函数是第一类对象:函数名指向的值可以被当做参数传递
1.函数名可以被传递
def func(): print('func') f = func # 函数名可以当做变量名 print(f) # f指向的也是函数func指向函数体代码的内存地址
2.函数名可以被当做参数传递给其他参数
def func(): print('from func') def index(args): print(args) args() # from func print('from index') index(func) #把func这个函数名传递给args,打印出来的结果为:<function func at 0x0000028A85681F28> #from index
3.函数名可以被当作函数的返回值
def index(): print('index') def func(): print('func') return index res = func() # func print(res) # 函数名的内存地址:<function index at 0x000001E573521F28> res() # 返回值:index
4.函数名可以被当作容器类型的参数
def func(): print('func') # func print(func()) # None l = [1,2,func,func()] # func print(l) # [1,2,<function func at 0x000001F7D79899D8>,None
二、函数嵌套
1.函数嵌套的调用
在函数内部调用其他函数
可以将复杂的逻辑简单化
# def max2(x,y): # if x > y: # return x # else: # return y # def max3(x,y,z): # res1=max2(x,y) # 先比较x和y的值 # res2=max2(res1,z) # 较大的值与z进行比较 # return res2 # 返回较大的值 # print(max3(7,8,9))
2.函数嵌套的定义
def outer(): x = 1 print('outer') def inner(): print('inner') # print(inner) return inner res = outer() # outer print(res) # <function outer.<locals>.inner at 0x000001F19F822AE8> res() # inner
三、名称空间
存放的是变量名与变量值的内存地址的绑定关系的地方
想要访问一个变量的值,必须先去名称空间拿到对应的名字,才能够访问变量的值
1.名称空间的分类
1》内置名称空间:python解释器提前给你定义好的名字(已经存放在内置名称空间),如len,max
2》全局名称空间:文件级别的代码(if for while 无论嵌套多少层,它们内部所创建的名字都是全局名称空间)
3》局部名称空间:函数体内创建的名字都属于局部名称空间
2.生命周期
内部名称空间:只要python解释器已启动立马创建,关闭python解释器的时候内置名称空间自动销毁
全局名称空间:只要右键运行py文件会自动创建,py文件程序运行结束自动销毁
局部名称空间:函数调用的时候自动创建,函数指向结束立即销毁(动态创建动态销毁)
3.名字查找的顺序
1》站在全局的角度:全局>内置
2》站在局部的角度:局部>全局>内置
x = 1 def f1(): x = 2 def f2(): x = 3 def f3(): x = 4 def f4: x = 5 print(x) f4() f3() f2() f1() #当需要调用f1的时候,会站在f4的局部去取值,如果f4没值就会取f3的值,按照局部>全局>内置这个顺序去取值
注意:
函数在定义阶段查找名字的顺序就已经固定了 不会因为函数的调用位置变化
四、作用域
1.全局作用域
全局有效:内置名称空间 全局名称空间
2.局部作用域
局部有效 : 局部名称空间
3.glolal
在局部修改全局的变量,如果需要修改多个,用逗号隔开
x = 1 def func(): x = 2 func() print(x) # 1 #首先,调用函数func在全局名称空间,所以要站在全局名称空间这个角度去看,就不需要考虑 #局部名称空间了,全局有 x = 1 这个数,所以打印结果就为1 #如果就要将打印结果变为局部 x = 2这个数呢?该怎么操作? x = 1 def func(): global x # 在局部修改全局的变量 x = 2 func() print(x) # 2
4.nonlocal
在局部修改局部的变量,如果想修改多个,用逗号隔开
def func(): x = 1 def index(): nonlocal x # 局部修改局部 x = 2 index() print(x) func() # 2