一、装饰器的本质
1、本质就是一个python函数,一个闭包;
2、可以让其他函数在不需要做任何的代码变动,也不改变其调用方式的前提下,增加额外的功能;
3、应用场景:插入日记,性能测试,事务代理,缓存等场景.
二、标准装饰器书写语法
def timer(f):
def inner(*args,**kwargs):#无敌传参 聚合
'''功能之前执行的代码'''
ret=f(*args,**kwargs) #执行参数 打散
'''功能执行后执行的代码'''
return ret #函数的返回值
return inner
使用@timer放置在函数的上一行给函数添加装饰器.
@timer #func=timer(f) #1、执行time(f) -->inner; #2、func=inner #当 func() -> inner() 执行内部函数
import time #简单装饰器 def timer(f): def inner(*args,**kwargs): start_time=time.time() ret =f(*args,**kwargs) end_time=time.time() print('该代码的执行效率>>>%s'%(start_time-end_time)) return ret return inner @timer #func=timer(f) #1、执行time(f) -->inner; #2、func=inner #当 func() -> inner() 执行内部函数 def foo(a,b): time.sleep(1) print('这是一万行代码') return a+b foo(12,45)
三、带参数的装饰器(flag):控制装饰器是否执行装饰部分代码
应用场景分析
假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?
一个一个的取消掉? 没日没夜忙活3天。。。
过两天你领导想通了,再让你加上。。。
代码演示
核心分析
@outer(flag) #1、单纯执行outer(flag) -->timer #2、@与timer结合形成装饰器 #3、foo=timer() #4、timer() -->inner #5、foo=inner def foo(a,b):
import time flag=True def outer(flag): def timer(f): def inner(*args,**kwargs): if not flag: ret = f(*args, **kwargs) return ret else: start_time=time.time() ret =f(*args,**kwargs) end_time=time.time() print('该代码的执行效率>>>%s'%(start_time-end_time)) return ret return inner return timer @outer(flag) #1、单纯执行outer(flag) -->timer #2、@与timer结合形成装饰器 #3、foo=timer() #4、timer() -->inner #5、foo=inner def foo(a,b): time.sleep(1) print('这是一万行代码') return a+b @outer(flag) def foo2(a,b): time.sleep(1) print('这是二万行代码') return a+b @outer(flag) def foo3(a,b): time.sleep(1) print('这是三万行代码') return a+b foo(10,20) foo2(30,50) foo3(17,28)
四、多个装饰器装饰一个函数
1、就近原则,越靠近函数的装饰器先装饰,之后的装饰器,装饰被装饰的函数。
import time def swrap1(f): def inner(*args,**kwargs): print('来自装饰器1',1) f(*args,**kwargs) print('来自装饰器1',2) return return inner def swrap2(f): def inner(*args,**kwargs): print('来自装饰器2>>>',1) f(*args,**kwargs) print('来自装饰器2>>>',2) return return inner @swrap2 #func=swrap2(func) ->func=inner--1 ->inner--1=inner--2 @swrap1 #func=swrap1(func) ->func=原func func=inner--1 表示swrap1中的inner def func(a,b): print('我是函数本身func') func(10,20) #本质执行的是inner--2() #2-1 1-1 本身 1-2 2-2
五、登陆注册装饰器示例
dic_status = { 'username': None, 'status': False } def login(f): def inner(): print(dic_status) if dic_status['status']==False: username=input("请输入用户名:") password=input("请输入密码:") with open('register','r',encoding='utf-8') as f1: for line in f1: lst=line.strip().split('|') if username.strip()==lst[0] and password.strip()==lst[1]: print('登录成功') dic_status['status']=True dic_status['name']=username ret = f() """被装饰函数执行之后的操作""" print(dic_status) return ret else: print("登录失败!") print(dic_status) return False else: ret = f() """被装饰函数执行之后的操作""" return ret return inner @login def article(): print('欢迎登录文章页面') @login def diary(): print('欢迎登录日记页面') @login def comment(): print('欢迎登录评论页面') article() diary() comment()
register文件
alex|123
wusir|456