python中的装饰器

装饰器(Decorators)是Python的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简短,也更符合Python规范(Pythonic)。

def a_new_decorator(a_func): def wrapTheFunction(): print(“I am doing some boring work before executing a_func()”) a_func() print(“I am doing some boring work after executing a_func()”) return wrapTheFunctiondef a_function_requiring_decoration(): print(“I am the function which needs some decoration to remove my foul smell”)a_function_requiring_decoration()#outputs: “I am the function which needs some decoration to remove my foul smell”a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)#now a_function_requiring_decoration is wrapped by wrapTheFunction()a_function_requiring_decoration()#outputs:I am doing some boring work before executing a_func()# I am the function which needs some decoration to remove my foul smell# I am doing some boring work after executing a_func()

上面的代码可以更简洁一些:

def a_new_decorator(a_func): def wrapTheFunction(): print(“I am doing some boring work before executing a_func()”) a_func() print(“I am doing some boring work after executing a_func()”) return wrapTheFunction@a_new_decoratordef a_function_requiring_decoration(): print(“I am the function which needs some decoration to remove my foul smell”)a_function_requiring_decoration()#outputs:I am doing some boring work before executing a_func()# I am the function which needs some decoration to remove my foul smell# I am doing some boring work after executing a_func()

其中@a_new_decorator(注意语句位置,须位于被装修函数之前)等价于下列语句:

a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)

如果需要获取被装饰函数的函数名,需要使用functools.wraps函数:

from functools import wrapsdef a_new_decorator(a_func): @wraps(a_func) def wrapTheFunction(): print(“I am doing some boring work before executing a_func()”) a_func() print(“I am doing some boring work after executing a_func()”) return wrapTheFunction@a_new_decoratordef a_function_requiring_decoration(): “””Hey yo! Decorate me!””” print(“I am the function which needs some decoration to ” “remove my foul smell”)print(a_function_requiring_decoration.__name__)# Output: a_function_requiring_decoration

否则,print(a_function_requiring_decoration.__name__)的返回结果将是wrapTheFunction。

装饰器能有助于检查某个人是否被授权去使用一个web应用的端点(endpoint)。它们被大量使用于Flask和Django web框架中。这里是一个例子来使用基于装饰器的授权:

from functools import wrapsdef requires_auth(f): @wraps(f) def decorated(*args, **kwargs): auth = request.authorization if not auth or not check_auth(auth.username, auth.password): authenticate() return f(*args, **kwargs) return decorated

日志是装饰器运用的另一个亮点。这是个例子:

from functools import wrapsdef logit(func): @wraps(func) def with_logging(*args, **kwargs): print(func.__name__ + ” was called”) return func(*args, **kwargs) return with_logging@logitdef addition_func(x): “””Do some math.””” return x + xresult = addition_func(4)# Output: addition_func was called

装饰器也可以带参数,我们将上面日志的例子修改一下,允许指定保存日志的位置:

from functools import wrapsdef logit(logfile=’out.log’): def logging_decorator(func): @wraps(func) def wrapped_function(*args, **kwargs): log_string = func.__name__ + ” was called” print(log_string) # Open the logfile and append with open(logfile, ‘a’) as opened_file: # Now we log to the specified logfile opened_file.write(log_string + ”) return func(*args, **kwargs) return wrapped_function return logging_decorator@logit()def myfunc1(): passmyfunc1()# Output: myfunc1 was called# A file called out.log now exists, with the above string@logit(logfile=’func2.log’)def myfunc2(): passmyfunc2()# Output: myfunc2 was called# A file called func2.log now exists, with the above string

类也可以用来构建装饰器:

class logit(object): _logfile = ‘out.log’ def __init__(self, func): self.func = func def __call__(self, *args): log_string = self.func.__name__ + ” was called” print(log_string) # Open the logfile and append with open(self._logfile, ‘a’) as opened_file: # Now we log to the specified logfile opened_file.write(log_string + ”) # Now, send a notification self.notify() # return base func return self.func(*args) def notify(self): # logit only logs, no more pass

这个实现有一个附加优势,在于比嵌套函数的方式更加整洁,而且包裹一个函数还是使用跟以前一样的语法:

logit._logfile = ‘out2.log’ # if change log file@logitdef myfunc1(): passmyfunc1()# Output: myfunc1 was called

我们给logit创建子类,来添加email的功能。

class email_logit(logit): ”’ A logit implementation for sending emails to admins when the function is called. ”’ def __init__(self, email=’admin@myproject.com’, *args, **kwargs): self.email = email super(email_logit, self).__init__(*args, **kwargs) def notify(self): # Send an email to self.email # Will not be implemented here pass

郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
用户投稿
上一篇 2022年6月19日 15:13
下一篇 2022年6月19日 15:13

相关推荐

  • 存储过程语法(sql server存储过程语法)

    今天小编给各位分享存储过程语法的知识,其中也会对sql server存储过程语法进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧! oracle存储过程基本语法…

    2022年11月26日
  • 全民K歌升级新版本7.0之后,有哪些隐藏功能?

    作者:高百烈来源:知乎 这个功能,旧版并没有,要升级到全新的全民K歌7.0版本才能发现。 作为朋友圈当代K歌之王,我费了不少功夫才抢到内测版本。有一说一,全民K歌的路子真的很野,新…

    2022年11月25日
  • 《光遇》11月25日红石在哪里 11.25红石位置

    光遇11月25日的红石出现在霞谷圆梦村,许多小伙伴都还不知道它具体在哪,下面就让小编来给大家介绍一下光遇11.25红石的位置,感兴趣的小伙伴快来看看吧。 光遇11.25红石位置 1…

    2022年11月25日
  • 《光遇》11月25日季节蜡烛在哪 11.25季节蜡烛位置2022

    光遇季节蜡烛的位置每天都会变化,今天出现在了雨林地区,下面小编就给大家带来了光遇11.25季节蜡烛位置分享,有需要的小伙伴不要错过哦。 光遇11.25季节蜡烛位置2022 今日季节…

    2022年11月25日
  • 上手Reno8 Pro体验跨屏互联 实在太方便!

    11月已经来到了月底,在手机品牌又要推出新一年度的新品手机之前,我们来点评一下今年令人惊喜的产品。如OPPO的Reno8 Pro系列,该系列搭载双芯影像配置获得了很多消费者的认可。…

    2022年11月25日
  • 什么是推广cpa一篇文章带你看懂CPA推广渠道

    CPA渠道 CPA指的是按照指定的行为结算,可以是搜索,可以是注册,可以是激活,可以是搜索下载激活,可以是绑卡,实名认证,可以是付费,可以是浏览等等。甲乙双方可以根据自己的情况来定…

    2022年11月25日
  • 《宝可梦朱紫》桩子是什么?二级神封印桩位置一览

    宝可梦朱紫中有一种叫做二级神封印桩的特殊收集道具,很多玩家不知道宝可梦朱紫桩子是什么,下面就带来宝可梦朱紫二级神封印桩位置一览,感兴趣的小伙伴不要错过,希望能帮助到大家。 二级神封…

    2022年11月24日
  • 《宝可梦朱紫》太晶水地龙捕捉位置一览 太晶水地龙在哪里捕捉

    近日在贴吧看到有许多玩家在宝可梦朱紫中遇到了《宝可梦朱紫》太晶水地龙捕捉位置一览的问题,又不知道该怎么办。今天在这里,小编为大家带来的就是这个问题的解方案,只要你跟着小编的节奏来,…

    2022年11月24日
  • 华为手机怎么扫一扫连接wifi(手机扫一扫在哪里)

    手机浏览器可以用来浏览网页、看新闻、看视频,还能搜索问题,在我们的工作生活中浏览器占据着非常重要的位置。手机浏览器除了这些作用,其实它隐藏着其他功能,比如:扫一扫。扫一扫可不只是用…

    2022年11月24日
  • 三星手机截屏(三星手机截屏图片在哪个文件夹)

    本文主要讲的是三星手机截屏,以及和三星手机截屏图片在哪个文件夹相关的知识,如果觉得本文对您有所帮助,不要忘了将本文分享给朋友。 三星手机截屏怎么截 三星手机四种截屏方法 1、普通截…

    2022年11月24日

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息