装饰器
Posted xufengnian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器相关的知识,希望对你有一定的参考价值。
1.什么是装饰器
器:指的是具备某一功能的工具
装饰:指的是为被装饰器对象添加新功能
装饰器就是用来为被装饰器对象添加新功能的工具
注意:装饰器本身可以是任意可调用对象,被装饰器的对象也可以是任意可调用对象
2.为何要用装饰器
软件的开发要遵循一个原则,开放封闭原则。
开放封闭原则:软件实体应该对扩展开放,对修改关闭,其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。
遵循开放封闭原则的话,则必须要使用到装饰器
装饰器的实现必须遵循两大原则:
1.不修改被装饰对象的源代码
2.不修改被装饰对象的调用方式
装饰器的目标:就是遵循1和2原则的前提下为被装饰对象添加上新功能
3.怎么使用装饰器
这里写了一个简单的统计执行时间的装饰器
import time def timmer(func): def wrapper(*args,**kwargs): start=time.time() res=func(*args,**kwargs) end=time.time() print(end-start) return res return wrapper @timmer def index(name): print(‘welcome to %s‘ %name) time.sleep(2) index(‘shanghai‘)
装饰器模板
def timmer(func): def wrapper(*args,**kwargs): #被装饰函数执行前干些什么 res=func(*args,**kwargs) #被装饰函数开始执行 #被装饰函数执行后干些什么 return res return wrapper
装饰器的语法糖
在被装饰对象正上方单独一行写@装饰器的名字
运行原理:
python解释器一旦运行到@装饰器的名字,就会调用装饰器,然后将装饰函数的内存地址当做参数传给装饰器,最后将装饰器调用的结果赋值给原函数名
叠加多个装饰器
解释@语法的时候是自下而上运行
而执行装饰器内的那个wrapper函数时是自上而下
import time def timmer(func): def wrapper(*args,**kwargs): start=time.time() res=func(*args,**kwargs) end=time.time() print(end-start) return res return wrapper def outer(func): def wrapper(*args,**kwargs): res=func(*args,**kwargs) print(func) time.sleep(1) return res return wrapper @outer @timmer def index(name): print(‘welcome to %s‘ %name) time.sleep(2) index(‘shanghai‘)
有参装饰器
import time current_user={‘username‘:None} # 补充:所有的数据类型的值自带布尔值,可以直接当作条件去用,只需要记住布尔值为假的那一些值即可(0,空,None) def login(engine=‘file‘): #engine=‘mysql‘ def auth(func): #func=最原始那个index的内存地址 def wrapper(*args,**kwargs): if current_user[‘username‘]: print(‘已经登录过了,无需再次登陆‘) res=func(*args,**kwargs) return res if engine == ‘file‘: inp_user = input(‘please input your username: ‘).strip() inp_pwd = input(‘please input your password: ‘).strip() if inp_user == ‘egon‘ and inp_pwd == ‘123‘: print(‘login successfull‘) current_user[‘username‘]=inp_user # 在登陆成功之后立刻记录登录状态 res=func(*args,**kwargs) # res=最原始那个index的内存地址(*args,**kwargs) return res else: print(‘username or password error‘) elif engine == ‘mysql‘: print(‘基于mysql的认证机制‘) elif engine == ‘ldap‘: print(‘基于ldap的认证机制‘) else: print(‘无法识别的认证源‘) return wrapper return auth @login(‘file‘) #@auth # index=auth(最原始那个index的内存地址) #index=wrapper def index(): print(‘welcome to index page‘) time.sleep(3) @login(‘file‘) def home(name): print(‘welcome %s to home page‘ %name) time.sleep(2) return 123 index() #wrapper() res=home(‘egon‘) print(res) # 有参装饰器的模板 def outter1(x,y,z): def outter2(func): def wrapper(*args,**kwargs): res=func(*args,**kwargs) return res return wrapper return outter2
以上是关于装饰器的主要内容,如果未能解决你的问题,请参考以下文章