本文共 3261 字,大约阅读时间需要 10 分钟。
内部函数 闭包和装饰器的基础
思想:内部函数主要是为了实现闭包,而装饰器又是基于闭包
内部函数-闭包-装饰器是一个连贯的知识点
函数里面又声明的函数,声明的函数就是内部函数
特点
1.可以访问外部函数的变量
2.内部函数可以修改外部函数的可变类型的变量(如:list1)
3.内部函数修改全局的不可变变量时,需要在内部函数声明: global 变量名
内部函数修改外部函数不可变变量是,需要在内部函数中声明:nonlocal 变量名
def func(): n=100 #局部变量 list1 = [9,20,3,4] #声明内部函数 def inner_function(): nonlocal n #对list1里面的元素进行加n操作 for index,i in enumerate(list1): list1[index]=i+n #内部函数可以访问局部变量 list1.sort() n+=1 #函数单纯定义没有任何意义,需要调用一下内部函数 inner_function() print(list1) print('打印老大n',n)func()'''打印老大n 101'''
用debug调试,func()处设置断点
a=100 #全局变量def func(): b=100 #局部变量 def inner_func(): c=88 #尝试打印a,b,c,的值 print(a,b,c) inner_func()func()'''100 100 88'''
a=100 #全局变量def func(): b=100 #局部变量 def inner_func(): global a nonlocal b c=88 #尝试修改 c+=12 b+=12 a+=10 #尝试打印a,b,c,的值 print(a,b,c) #调用内部函数 inner_func() print(locals())func()'''110 112 100{'inner_func':.inner_func at 0x000002373BC9A310>, 'b': 112}'''
locals() 查看当前函数中声明的内容有哪些,以字典形式输出
globals()查看全局变量有哪些,以字典形式输出,里面有一些系统的键值对
闭包
在函数中提出的概念
条件
1.外部函数中定义了内部函数
2.外部函数有返回值
3.返回的值是内部函数(不能加括号,加括号表示调用)
4.内部函数引用了外部函数变量的值
格式
'''def 外部函数(): ... def 内部函数(): ... return 内部函数'''
例子
#外部访问内部函数def func(): a=100 def inner_func(): b=99 print(a,b) return inner_func #内部函数通过return扔出x=func()print(x)#x就是内部函数,x()表示调用函数x()'''.inner_func at 0x00000184D1A1A310>100 99'''
def func(a,b): c=10 def inner_func(): s=a+b+c print('结果:',s) return inner_func#调用funcifunc=func(6,9) #ifunc就是inner_func#调用返出来的内部函数ifunc()'''结果: 25'''
——————分割线——————
装饰器 依赖闭包 闭包的基础上多一个条件:函数作为外层函数的参数
应用场景:加入购物车、付款、修改地址……都要判断用户的登录状态,依赖装饰器
引入
def func(num): a=100 def inner_func(): nonlocal a #修改局外变量 nonlocal num #传进来的参数num也可以修改 num+=1 for i in range(num): a+=1 print('修改后a的值:',a) return inner_func #此处千万不要带括号#调用funcf = func(5) #func返回的是内部函数f() #f变为inner_func,()进行调用'''修改后a的值: 105'''
地址引用
def test(): #声明函数 print('---test---')t=test #函数test赋值给t#类比a=10 #声明整型变量b=a #a值赋给btest()t() #即调用test'''---test------test---'''
def func(x): print('--->',x)a=10func(a)'''---> 10'''
def test(): #声明函数 print('---test---')t=testdef func(f): print(f) f() #0x00000199AB91F040 去这个地方调用ffunc(test) #f=test,同t'''---test---'''
整体上只有两个函数和一个调用
特点
1.函数A作为参数出现,函数B接收函数A作为参数
2.要有闭包的特点
#定义一个装饰器def decorator(func): a=100 def wrapper(): #包装 func() print('--->111') print('--->222',a) return wrapper#使用装饰器@decorator#不改变原函数名字的情况下,对函数进行装饰#开发中已经定义好了一个函数,但后来发现函数定义的有问题,想再丰富一下函数#想再装饰一下#函数ABC都要调用D,后来AB调用D发现不满足条件,要求D改动,而C对D要求不变#不改变原名进行装饰def house(): print('我是毛坯房')house()'''我是毛坯房--->111--->222 100'''
decorator做了啥
def decorator(func): a=100 print('wrapper外层打印测试') def wrapper(): #包装 func() print('--->111') print('--->222',a) print('wrapper加载完成...') return wrapper@decoratordef house(): #被装饰函数 print('我是毛坯房')print(house)'''wrapper外层打印测试wrapper加载完成....wrapper at 0x000001B71917A3A0>'''
1.house被装饰函数
2.将被装饰函数作为参数传给装饰器decorator
3.执行decorator函数(底层完成执行)
4.将返回值又赋值给house
转载地址:http://vzegn.baihongyu.com/