首页 > 其他 > 详细

装饰器

时间:2019-07-14 09:12:31      阅读:70      评论:0      收藏:0      [点我收藏+]

一,装饰器定义阶段:

1. 什么是装饰器
器:指的是具备某一功能的工具
装饰:指的是为被装饰器对象添加新功能

装饰器就是用来为被装饰器对象添加新功能的工具
注意:装饰器本身可以是任意可调用对象,被装饰器的对象也可以是任意可调用对象

2. 为何要用装饰器
开放封闭原则:封闭指的是对修改封闭,对扩展开放
装饰器的实现必须遵循两大原则:
1. 不修改被装饰对象的源代码
2. 不修改被装饰器对象的调用方式
装饰器的目标:就是在遵循1和2原则的前提下为被装饰对象添加上新功能

二,装饰器的应用

技术分享图片

技术分享图片

上面的这张图中outter()的功能就是装饰器,它装饰了index函数,他在没有改变被调用对象的源代码和调用方式的前提下,实现了统计函数运行时间的功能,感官体验好像还是index()的调用。

装饰器升级版:装饰器同时装饰两个函数。下图中outter()函数是装饰器,index函数和home函数是被装饰对象。index()函数(其实是wrapper函数)不需要传参,而home()函数(其实是wrapper函数)需要传参,那么要想外部调用home()(其实是wrapper函数)就需要给定义阶段的wrapper()传形参,比如wrapper(name),然后调用wrapper()阶段才能传实参,但一个装饰器在同时需要兼顾两个函数,一个需要传值,另一个不需要传值,同时调用,就会报错。那么我们该如何解决呢????这时我们就需要对装饰器outter()内部函数wrapper()传入两个参数了叫做*args和**kwargs,众所周知这两个参数的作用(在形参中,这两个参数可以接收实参传来的多余位置参数和关键字参数;在实参中,*args这个参数可以将其后面的元组打散成位置实参给位置形参传值,**kwargs这个参数可以将其后面的字典形式的关键字参数打散,传给形参中的关键字参数),所以上图中index不传参,*args和**kwargs没有接收到多余的参数,形成了一个空的()和空的{},在下面调用func()的时候,func括号中(即index括号中)的*args将空元组打散,**kwarg将空字典打散,就没有什么参数传给index函数了。而home()传了位置实参“egon”,wrapper()形参中的*args默认接收了形参中多余的位置实参‘egon’,将‘egon’存元组的形式,而此时**kwargs还是一个空字典,到下面遇到func(*args,**kwargs),*args将(‘egon’)打散成字符串原封不动的传给了*args,**kwargs的一个空字典被打散没有了。这样两个函数都被装饰上了,添加上了新的功能,也并没有改变原函数的代码,也没改变他们的调用方式。

技术分享图片

 

 

注意:现在以home函数为例,如果home函数内部有个返回值(return 234),那么加上装饰器outter(),接收outter(home)的返回值,print(res=outter(home)) 返回值是None,因为这里的home()就是wrapper()。

 

 

技术分享图片

 

三,装饰器的语法糖

在被装饰函数上面一行加上@+装饰器,即,例如:

@timmer

def func()

表示装饰func()函数,意思是func=timmer(func),func是最原始的那个func的内存地址。

 运行原理:
 python解释器一旦运行到@装饰器的名字,就会调用装饰器,然后将被装饰函数的内存地址当作参数
 传给装饰器,最后将装饰器调用的结果赋值给原函数名

         技术分享图片

 

 

四,import time

 装饰器模板
def outter(func):
def wrapper(*args,**kwargs):
#在调用函数前加功能
res=func(*args,**kwargs) #调用被装饰的\也就是最原始的那个函数
 在调用函数后加功能
return res
return wrapper

@outter #index=outter(index) #index=wrapper
def index():
print(‘welcome to index page‘)
time.sleep(3)

index()

 

五,叠加多个装饰器

执行步骤:解释语法的时候,是自下而上(解释@语法的时候),而执行装饰器的时候是自上而下的。

技术分享图片

 

装饰器

原文:https://www.cnblogs.com/zhangchaocoming/p/11182922.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!