1.函数对象:函数是第一类对象
特点
1:可以被引用
1 def func(): 2 pass 3 f =func 4 print(f is func)
2:可以当做参数传给其它函数
1 def foo(): 2 print('from foo') 3 def bar(func): 4 print('func') 5 func() 6 bar(foo) #foo就相当于func
3:可以当做函数的返回值
1 def foo(): 2 print('foo') 3 def ddd(func): 4 print(func) 5 return func 6 ddd(foo)()
4:可以当做容器类型的一个元素
1 def get(): 2 print('get') 3 def put(): 4 print('put') 5 def auth(): 6 print('auth') 7 func_dic={ 8 'get':get, 9 'put':put, 10 'auth':auth 11 } 12 # print(func_dic) 13 def main(): 14 while True: 15 cmd = input('>>:').strip() 16 if not cmd :continue 17 if cmd in func_dic: 18 func_dic[cmd]() 19 if __name__ == '__main__': 20 main()
2.函数嵌套调用(可以吧大的问题分成一个个小的问题,然后调用,缩减代码)
1 def my_max2(x,y): 2 '''两个数比较大小''' 3 return x if x>y else y 4 print('最大的数是:%s'%my_max2(1,2)) 5 def my_max4(a,b,c,d): 6 '''四个数比较大小''' 7 res1 = my_max2(a,b) 8 res2 = my_max2(res1,c) 9 res3 = my_max2(res2,d) 10 return res3 11 print('最大的数是:%s'%my_max4(5,8,1,4))
3.函数嵌套定义
1 def f1(): 2 x=1 3 def f1(): 4 def f3(): 5 pass 6 f1()
4.名称空间:指的是内存级别隔离的空间(存放名字与值绑定关系的地方)
分类:
内置名称空间:会随着python解释器的运行而产生,如果解释器关闭则回收,存放python解释器自带的名字
全局名称空间:执行python文件时产生,文件执行结束后回收,存放的文件级别的名字
局部名称空间:只有在调用函数时才会临时产生,在函数调用结束后就回收了,存放的函数内部定义的名字
三类名称空间的加载顺序:内置名称空间-->全局名称空间-->局部名称空间
查找名字的顺序:
在局部调用:局部命名空间--->全局命名空间--->内置命名空间
站在全局范围找:全局----内置----局部
5.作用域:就是作用范围
全局作用域:全局命名空间和内置命名空间(文件执行的时候生效,在文件执行结束后就失效了)
全局存活,全局有效
局部作用域:局部命名空间(只在函数调用时生效,函数调用结束后失效)
临时存活,局部有效
强调:作用域关系在函数定义阶段就已经固定了,与调用位置无关
1 x = 1 2 def f1(): 3 x=2 4 def f2(): 5 # x=3 6 print('f2',x) 7 return f2 8 f = f1() 9 10 def bar(): 11 x = 'bar' #x输出的还会上面函数里面的,如果x=3注释了,就输出2, 12 # 它不会输出bar,因为在函数定义阶段就已经固定了 13 f() 14 bar()
6.global与nonlocal
global:将局部变量强制转换成全局变量(一般不到迫不得已不要这样强转)
1 x=1 2 def func(): 3 # global x 4 x=2 5 print(globals()) # 查看全局 6 print(locals()) # 查看局部 7 func() 8 print(x) #打印的是全局变量1,如果加上global就成2了
nonlocal:让内部函数中的变量在上一层函数中生效,外部必须有
1 x=5 2 def o(): 3 x = 1 4 def f1(): 5 # x= 2 6 def f2(): 7 nonlocal x #修改本层函数外的变量,如果本层函数外 8 # 没有,就去找上一层的,但是不会去修改全局的 9 x = 100 10 f2() 11 print(x) 12 f1() 13 o() 14 print(x)
7.闭包函数:定义在函数内部的函数,包含对外部作用域而非全局作用于的名字的引用,该函数就是闭包函数
1 x = 1 2 def f1(): 3 y =2222 4 def f2(): 5 print(y) 6 return f2 7 f =f1() 8 print(f) 9 print(f.__closure__) #判断是不是闭包函数 10 print(f.__closure__[0].cell_contents) #输出2222 #查看闭包的内容
1 from urllib.request import urlopen 2 def index(url): 3 def inner(): 4 return urlopen(url).read() 5 return inner 6 baidu = index('http://www.baidu.com') 7 print(baidu()) 8 print(baidu()) 9 print(baidu())
1 from urllib.request import urlopen 2 def index(url): 3 return urlopen(url).read() 4 print(index('http://www.baidu.com')) 5 print(index('http://www.baidu.com')) 6 print(index('http://www.baidu.com')) 7 print(index('http://www.baidu.com'))