本篇内容主要讲解“Python装饰器的使用方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python装饰器的使用方法是什么”吧!
1. 什么是装饰器
对于受到封装的原函数比如f来说,装饰器能够在f函数执行前或者执行后分别运行一些代码。
2. 装饰器的结构
装饰器也是一个函数,它装饰原函数f或类cls后,再返回一个函数g
装饰一个函数:
def decorator(f): # 定义要返回的函数 def g(): print('函数f执行前的动作') f() print('函数f执行后的动作') return g
装饰一个类:
def decorator(cls): # 定义要返回的函数 def g(): print('类cls执行前的动作') f() print('类cls执行后的动作') return g
使用装饰器很简单,@+自定义装饰器 装饰要想装饰的函数。
3. 为什么要这样
要想理解装饰器为什么要有这种结构,要首先想明白装饰器的目标是什么。
它的价值在于为原函数f增加一些行为,前提必须不能破坏函数f,所以肯定不能改变f的内部结构,所以只能在调用f前后定义一些行为。
同时,装饰器函数decorator返回值又是什么?你可以思考下,返回一个函数是再好不过的了,它包装了原函数f.
4. 装饰一个函数
printStar函数接收一个函数f,返回值也是一个函数,所以满足装饰器的结构要求,所以printStar是一个装饰器。
def printStar(f): def g(): print('*'*20) f() print('*'*20) return g
printStar装饰器实现f函数执行前、后各打印20个*字符。
使用printStar:
@printStar def f(): print('hello world')
调用:
if __name__ == '__main__': ### 改变函数功能 f()
打印结果:
******************** hello world ********************
可以很方便的装饰要想装饰的其他函数,如下:
@printStar def g(): print('welcome to Python')
5. 装饰一个类
除了可以装饰函数f外,还可以装饰类cls,两者原理都是一样的。
下面给出一个装饰器实现单例模式的例子,所谓单例就是类只有唯一实例,不能有第二个。
def singleton(cls): instance = {} def get_instance(*args, **kwargs): if cls not in instance: instance[cls] = cls(*args, **kwargs) return instance[cls] return get_instance
定义字典instance,键值对分别为类和实例,这样确保只cls()一次。
使用装饰器singleton修饰类:
@singleton class CorePoint: pass
测试:
if __name__ == '__main__': ### 改变类的功能 c1 = CorePoint() c2 = CorePoint() print(c1 is c2) # True
6. 装饰器层叠
上面原函数f不仅能被一个装饰器修饰,还能被n多个装饰器修饰。
下面再定义一个装饰器printLine,被修饰函数执行前后打印20个:
def printLine(f): def g(): print('-'*20) f() print('-'*20) return g
使用上文定义好的printStar和printLine同时装饰函数f:
@printStar @printLine def f(): print('hello world')
此时再调用函数f:
if __name__ == '__main__': ### 改变函数功能 f()
打印结果:
******************** -------------------- hello world -------------------- ********************
f被装饰后,先打印*,再打印 -
层叠多一层,原函数f就变强大一层。使用装饰器,还能实现功能抽离,进一步实现松耦合。
7. 温馨提醒
打印原函数f的名字__name__,结果为f
In [1]: def f(): ...: pass In [4]: f.__name__ Out[4]: 'f'
但是,被装饰后函数名字f变为g,这不是我们希望的!
@printStar def f(): pass f() f.__name__ # g
Python提供的解决方案:使用functools模块中的wraps装饰器:
from functools import wraps def printStar(f): @wraps(f) def g(): print('*'*20) f() print('*'*20) return g
此时再打印被装饰后f的名字,显示f,正常!
到此,相信大家对“Python装饰器的使用方法是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。