Looking For Anything Specific?

python函数知识七 闭包、装饰器一(入门)、装饰器二(进阶)

21.闭包 闭包:在嵌套函数内,使用非全局变量(且不使用本层变量) 闭包的作用:1.保证数据的安全性(纯洁度)。2.装饰器使用 .__closure__判断是否是闭包 def func(): a = 1 def foo(): print(a) return foo ret = func() ret() #例子 def func(): avg_lst = [] def foo(pirce): avg_lst.append(pirce) avg = sum(avg_lst) / len(avg_lst) return avg return foo ret = func() print(ret(1500)) print(ret(1600)) print(ret.__closure__)#结果:(,)证明是闭包 print(func.__closure__)#结果:None,不是闭包 print(ret.__code__.co_freevars)#获取的是自由变量 print(ret.__code__.co_varnames)#获取的是局部变量 22.装饰器一(入门) 1.一个装饰器装饰多个函数 开放封闭原则:扩展是开放的(增加新功能),源码是封闭的(修改已经实现的功能) 作用:在不改变源代码及调用方式的基础下额外增加新功能。 装饰器:用来装饰的工具 2.版一: import time start_time = time.time def func(): time.sleep(2)#睡眠s模拟网络延时 print("我要飞") func() print(time.time - start_time) #改变了源代码 3.版二: def times(f): start_time = time.time() f() print(time.time() - start_time) def foo(): time.sleep(3) print("我飞的比你高") #times(foo)#改变了调用方式 s = foo foo = times foo(s)#不改变调用方式 4.版三:(low版装饰器) def times(f): def inner(): start_time = time.time() f() print(time.time() - start_time) return inner def foo(): time.sleep(3) print("我飞的比你高") foo = times(foo) foo() 5.版四: def wrapper(f): def inner(a): start_time = time.time() f(a) print(time.time() - start_time) return inner#切记不加括号 def func(a): print(f"{a}你不行") func = wrapper(func) func("alex") #传输多个数据,用*args,**kwargs 6.版五(标准版装饰器): @wrapper#语法糖:必须放在要装饰的函数的正上方 def wrapper(f):#f是要被装饰的函数名 def inner(*args,**kwargs): "被装饰前" start_time = time.time() ret = f(*args,**kwargs) print(time.time() - start_time) "被装饰后" return ret return inner#切记不加括号 @wrapper#语法糖 -->func = wrapper(func) def func(*args,**kwargs): print(f"{a}你不行") return "我可以返回了" #func = wrapper(func)#有语法糖不用多次赋值 func("alex") 23.装饰器二(进阶) 1.有参装饰器: ​ 有参装饰器:在基础装饰器的基础上再套一层函数 #有参装饰器实现登陆验证 msg = """ QQ 微信 抖音 请输入您要登录的的app: """ chose = input(msg).upper() dict_flag = {'username':None,'flag':False} def auth(a): def wrapper(f): def inner(*args,**kwargs): if dic_flag['flag']: fun(*args,**kwargs) else: if argv =="QQ": print("欢迎登陆QQ") user = intput("user:") pwd = input("passwd:") if user == "alex" and pwd == "alex123": dict_flag["flag"] = True dict_flag["username"] = user foo(*args,**kwargs) else: print("用户名或密码错误!") return inner return wrapper @auth(chose) """ 语法糖拆分: wrapper = auth(chose) foo = wrapper(foo) """ def foo(): print("这是被装饰的函数") foo() 2.多个装饰器装饰一个函数: ​ 当被装饰的函数正上方有多个装饰器,先执行里被装饰函数最近的装饰器(小技巧:进入装饰器,从上往下,走到最后一个装饰器,执行被装饰的函数,退出装饰器从下往上) def wrapper1(f): def inner1(*args,**kwargs): print("这是第一个装饰器开始") f(*args,**kwargs) print("这是第一个装饰器结束") return return inner1 def wrapper2(f): def inner2(*args,**kwargs): print("这是第二个装饰器开始") f(*args,**kwargs) print("这是第二个装饰器结束") return return inner2 @wrapper1 @wrapper2 """ 两个语法糖等价于: foo = wrapper2(foo)#foo == inner2 foo = wrapper1(foo)#foo = wrapper(inner2),foo == inner1 foo()#-->inner1() """ def foo(): print("这是被装饰的函数") foo() ''' 结果: 这是第一个装饰器开始 这是第二个装饰器开始 这是被装饰的函数 这是第二个装饰器结束 这是第一个装饰器结束 ''