文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-06-17 06:49

关注

本篇内容主要讲解“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)

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

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装饰器的介绍及使用方法”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯