温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Python装饰器的介绍及使用方法

发布时间:2021-08-03 18:02:19 来源:亿速云 阅读:125 作者:chen 栏目:编程语言

本篇内容主要讲解“Python装饰器的介绍及使用方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python装饰器的介绍及使用方法”吧!

app = Flask(__name__) @app.route("/") def hello(): return "Hello World!"

1、装饰器是什么

装饰器是Python语言中的高级语法。主要的功能是对一个函数、方法、或者类进行加工,作用是为已经存在的对象添加额外的功能,提升代码的可读性。
装饰器是设计模式的一种,被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等

2、装饰器的语法

装饰器的语法如下:

当前Python的装饰器语法如下:

@dec2 @dec1 def func(arg1, arg2, ...):     ....     return funx  上面的代码相当于:  def func(arg1, arg2, ...):     pass func = dec2(dec1(func))

装饰器可以用def的形式来定义。装饰器接收一个可调用对象作为输入参数,并返回一个新的可调用对象。
装饰器新建了一个可调用对象,也就是return 返回的函数funx,在新增的函数中,可以添加我们需要的功能,并通过调用原有函数来实现原有函数的功能。

3、装饰器的使用

3.1不带参数的装饰器

定义装饰器非常的简单:

def deco(func):     """无参数调用decorator声明时必须有一个参数,这个参数将接收要装饰的方法"""     print "before myfunc() called."     func()     print "after myfunc() called."     return func  @deco def myfunc():     print " myfunc() called."   myfunc() myfunc()

定义好装饰器后,,,即可使用。上面这个装饰器在使用的时候有一个问题,即只在***次被调用,并且原来的函数多执行一次。执行输出如下:

before myfunc() called.   myfunc() called. after myfunc() called.  myfunc() called.   --函数多执行一次的输出  myfunc() called.   --第二次调用,装饰器不生效

要保证新函数每次被调用,使用下面的方法来定义装饰器

def deco(func):     """无参数调用decorator声明时必须有一个参数,这个参数将接收要装饰的方法"""     def _deco():         print "before myfunc() called."         func()         print "after myfunc() called."         #return func 不需要返回func     retrun _deco @deco def myfunc():     print " myfunc() called."     return 'OK' myfunc() myfunc()

函数输出如下:

before myfunc() called.  myfunc() called.   after myfunc() called. before myfunc() called.  myfunc() called.   after myfunc() called.

这样可以看到,装饰器每次都得到了调用。

3.2带参数的函数进行装饰器

def deco(func):     def _deco(a, b):         print("before myfunc() called.")         ret = func(a, b)         print("  after myfunc() called. result: %s" % ret)     return ret return _deco  @deco def myfunc(a, b):     print(" myfunc(%s,%s) called." % (a, b))     return a + b   myfunc(1, 2) myfunc(3, 4)

输出:

before myfunc() called. myfunc() called. After myfunc() called. result: 3 before myfunc() called. myfunc() called. After myfunc() called. result: 7

内嵌函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数。

3.3装饰器带参数

def decoWithArgs(arg): """由于有参数的decorator函数在调用时只会使用应用时的参数而不接收被装饰的函数做为参数,    所以必须返回一个decorator函数, 由它对被装饰的函数进行封装处理""" def newDeco(func):    #定义一个新的decorator函数     def replaceFunc():    #在decorator函数里面再定义一个内嵌函数,由它封装具体的操作         print "Enter decorator %s" %arg    #进行额外操作         return func()    #对被装饰函数进行调用     return replaceFunc return newDeco    #返回一个新的decorator函数  @decoWithArgs("demo") def MyFunc():    #应用@decoWithArgs修饰的方法     print "Enter MyFunc"  MyFunc()    #调用被装饰的函数

输出:
nter decorator demo
Enter MyFunc

这个情形适用于原来的函数没有参数,新增加打印的情况。常见适用的地方是增加函数的打印日志。

3.4对参数数量不确定的函数进行装饰

下面的例子是一个邮件异步发送的例子,函数的参数数据部确定,装饰器实现了对于邮件发送函数的异步发送。

from threading import Thread  def async(f):     def wrapper(*args, **kwargs):         thr = Thread(target = f, args = args, kwargs = kwargs)         thr.start()     return wrapper  @async def send_async_email(msg):     mail.send(msg)  def send_email(subject, sender, recipients, text_body, html_body):     msg = Message(subject, sender = sender, recipients = recipients)     msg.body = text_body     msg.html = html_body     send_async_email(msg)

并且这个装饰器可以适用一切需要异步处理的功能,做到非常好的代码复用。

3.5让装饰器带类参数

class locker:     def __init__(self):         print("locker.__init__() should be not called.")               @staticmethod     def acquire():         print("locker.acquire() called.(这是静态方法)")               @staticmethod     def release():         print("  locker.release() called.(不需要对象实例)")   def deco(cls):     '''cls 必须实现acquire和release静态方法'''     def _deco(func):         def __deco():             print("before %s called [%s]." % (func.__name__, cls))             cls.acquire()             try:                 return func()             finally:                 cls.release()         return __deco     return _deco   @deco(locker) def myfunc():     print(" myfunc() called.")   myfunc() myfunc()

输出为:

before myfunc called [__main__.locker]. locker.acquire() called.(this is staticmethon) myfunc() called.   locker.release() called.(do't need object )  before myfunc called [__main__.locker]. locker.acquire() called.(this is staticmethon) myfunc() called.   locker.release() called.(do't need object )

装饰器总结

当我们对某个方法应用了装饰方法后, 其实就改变了被装饰函数名称所引用的函数代码块入口点,使其重新指向了由装饰方法所返回的函数入口点。由此我们可以用decorator改变某个原有函数的功能,添加各种操作,或者完全改变原有实现。

到此,相信大家对“Python装饰器的介绍及使用方法”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI