新网创想网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
本篇内容主要讲解“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装饰器的介绍及使用方法”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!