0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

让你学写Python装饰器的五大理由

马哥Linux运维 来源:xx 2019-03-02 10:06 次阅读

你必须学写Python装饰器的五个理由

----装饰器能对你所写的代码产生极大的正面作用

作者:Aaron Maxwell,2016年5月5日

Python装饰器是很容易使用的。任何一个会写Python函数的人都能够学会使用装饰器,比如下面这个:\

@somedecoratordef some_function(): print("Check it out, I"m using decorators!")

但是,写出一个装饰器是一个完全不一样的技能。而且这也不是,你不得不理解下面这些:

闭包

如何将函数作为"第一类"参数来使用

变量参数

参数解包

甚至是Python是如何装载源码的一些细节

所有这些都需要花很多时间去理解和掌握。而且当你已经有这么一堆事情要学的时候,这些值得你花时间吗?

对我来说,这个问题的答案已然是上千次的“肯定,是的,我会学习!”

写装饰器的最重要的好处是什么呢?在你每天的开发中,装饰器让你做什么做起来是很容易并且很强大的呢?

分析、日志以及指导

尤其是在大型软件中,我们通常需要专门来测试到底发生了什么,以及记录那些能量化不同行为的指标。通过在装饰器内部的函数或者方法里面封装这些重要的事件,这个装饰器能通俗易懂且容易地处理刚才这些所讲的需求。比如:

from myapp.log import logger def log_order_event(func): def wrapper(*args, **kwargs): logger.info("Ordering: %s", func.__name__) order = func(*args, **kwargs) logger.debug("Order result: %s", order.result) return order return wrapper @log_order_event def order_pizza(*toppings): # let"s get some pizza!

同样的方式可以被用来计数或者其他指标。

验证与运行检查

Python的类型系统是相当类型化了的,但是也是很动态的。对于它的这些所有的好处,也意味着某一些bugs能够悄悄产生,而这些bugs能够在编译的时候被更类型化的语言(比如Java)所捕获。即使更长远看,你可能需要强化更复杂的,在数据进出的时候能个性化检查。装饰器能让你易于处理所有这些,并能一次性地应用它到很多函数上。

假设:你有一堆函数,每个函数都返回一个字典,这个字典包含一个称作“summary”的字段。这个字段的值不能超过80个字符长度;如果违反了,就是不对的。这里给出一个装饰器,当条件不满足的时候它能够抛出一个值错误(ValueError),如下:

def validate_summary(func): def wrapper(*args, **kwargs): data = func(*args, **kwargs) if len(data["summary"]) > 80: raise ValueError("Summary too long") return data return wrapper @validate_summary def fetch_customer_data(): # ... @validate_summary def query_orders(criteria): # ... @validate_summary def create_invoice(params): # ...

创建框架

一旦你掌握了装饰器的编程,你将能够受益于使用装饰器的简单语法,而这让你增加语意给你的代码以便容易使用它。这就是下一个能够扩展Python自身语法的最好的工具。

实际中,很多流行的开源框架都在使用装饰器。网页应用框架Flask就使用了装饰器将URLs的路由交给那些处理HTTPS请求的函数。

# For a RESTful todo-list API. @app.route("/tasks/", methods=["GET"]) def get_all_tasks(): tasks = app.store.get_all_tasks() return make_response(json.dumps(tasks), 200) @app.route("/tasks/", methods=["POST"]) def create_task(): payload = request.get_json(force=True) task_id = app.store.create_task( summary = payload["summary"], description = payload["description"], ) task_info = {"id": task_id} return make_response(json.dumps(task_info), 201) @app.route("/tasks//") def task_details(task_id): task_info = app.store.task_details(task_id) if task_info is None: return make_response("", 404) return json.dumps(task_info)

在这里,你有一个被叫做app的全局的对象,它有一个被称作route(路由)的方法并接受特定参数。这个路由方法返回一个被应用到处理函数的装饰器。在这个“面罩”下发生了一些很错综复杂的的事情,但是从Flask的使用者角度看,所有这些复杂性是完全被隐藏起来的了。

以这样的方式使用装饰器在stock Python中也有体现。举个例子,完全使用对象系统是有赖于@classmethod和@property装饰器的:

class WeatherSimulation: def __init__(self, **params): self.params = params @classmethod def for_winter(cls, **other_params): params = {"month": "Jan", "temp": "0"} params.update(other_params) return cls(**params) @property def progress(self): return self.completed_iterations() / self.total_iterations()

这个类有3个不同的定义声明。但是,他们的语意是各不相同的。

1:constructor是一个正常方法

2:for_winter是一个类方法且提供一种类似于“车间”的东西

3:progess是只读、动态属性

对于日常来说,@classmethod和@property两个装饰器如此简单以致可以很容易扩展Python的对象语意

复用那些不可能复用的代码

Python提供给你一些很强大的工具用以封装代码为一个易用的形式,并带有充分的函数表示语法,支持函数式编程以及全面的对象系统。但是,装饰器也有它所不能捕获的某些形式的代码复用。

比如使用一个不可靠的API。你给那些通过HTTP对话的JSON发出一些请求的时候,API可以99.9%的时候工作正常。但是,有一小部分请求将使得服务器返回一个内部错误,然后你需要重试这些请求。在这个情况下,你将写一个重试逻辑,比如:

resp = None while True: resp = make_api_call() if resp.status_code == 500 and tries < MAX_TRIES:            tries += 1            continue        break    process_response(resp)

现在,假设你有十多个类似于make_api_call的函数,并且他们被所有代码调用。那么你是想要每次调用它们的时候写一个while循环呢?还是每次增加一个API调用函数的时候都把这段代码再写一遍?无论哪种选择都会产生大量的重复代码,除非你用装饰器。用了装饰器事情就简单了。

# 加了装饰器的函数会返回一个Response对象,# 这个对象有个一二status_code的属性,# 200表示成功;500表示服务器错误。def retry(func): def retried_func(*args, **kwargs): MAX_TRIES = 3 tries = 0 while True: resp = func(*args, **kwargs) if resp.status_code == 500 and tries < MAX_TRIES:                tries += 1                continue            break        return resp    return retried_func

上述例子可以让你方便使用装饰器@retry

@retry def make_api_call(): # ....

提升你的职业生涯

编写装饰器在一开始并不容易。它虽然不像火箭科学但是也需要你花很多努力去学习,去排除一些细微差异。很多开发者也从来不会通过这些麻烦而学习掌握装饰器编写。但是学习装饰器的确会给你优势。当你是你的团队里面学习如何写好装饰器的那个人的时候,并且你写的装饰器能解决一些实际问题的时候,其他开发者将会使用你的装饰器。因为,一旦这些装饰器编写的困难的部分被完成了,装饰器就会很容易使用。这就对你所写的代码产生极大的正面作用。这也会让你成为一个重要角色。

不论你如何编写装饰器,你会对下面你所要做的事情而感到兴奋,比如你即将能使用装饰器来做一些事情,以及装饰器是如何能永远改变你写Python代码的方式。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • python
    +关注

    关注

    55

    文章

    4778

    浏览量

    84439

原文标题:你必须学写 Python 装饰器的五个理由

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    亚马逊为何收购通讯公司Slack 有以下五大理由

    若干家潜在收购方的目标,它们对Slack开出的报价可能达到90亿美元。在这些收购方当中,就包括了亚马逊。亚马逊为何会收购Slack,国外媒体列举出了五大理由
    发表于 06-17 06:00 902次阅读

    从ESA-L系列频谱分析仪迁移到CXA X系列信号分析仪的三大理由

    从ESA-L系列频谱分析仪迁移到CXA X系列信号分析仪的三大理由
    发表于 09-28 16:56

    德州仪器转向微型器件的五大理由

    随着电子电路越来越小型,它们的组件越来越智能,并能更加快速地处理更多信息– 因此,在通常情况下,它们所需的芯片也前所未有地减少。多年以来“小型”一直是关键的半导体趋势。德州仪器拥有的多款微型器件可帮您克服各式应用中的设计难题。以下列出转向小型器件的五大理由。德州仪器LOGO
    发表于 07-29 08:28

    升级使用16800或16900系列逻辑分析仪的十大理由

    升级使用16800或16900系列逻辑分析仪的十大理由
    发表于 08-04 13:12 28次下载

    3D立体电视势不可挡的7大疑问和4大理由

    3D立体电视势不可挡的7大疑问和4大理由  10月28日在横滨举行的国际平板显示大会(FPDInternational)表明3D立体娱乐的家用化趋势已定,至少索尼、松下等日本消费电子巨头
    发表于 11-07 08:45 979次阅读

    由Windows 2000升级至2003/XP的10大理由

    由Windows 2000升级至2003/XP的10大理由  Windows Server 2003是在可靠的Windows 2000 Server系列的基础上生成的,它集成了功能强大的应用程序环境以开发全
    发表于 01-29 11:53 1071次阅读

    爱上苹果机的6大理由

    爱上苹果机的6大理由 1. 苹果不需要杀毒软件. 其实杀毒软件也是病毒.-杀毒软件的电脑变慢. 并且它跟病毒一样时时刻刻
    发表于 02-26 16:55 748次阅读

    使用LabVIEW软件进行数据采集和信号处理的10大理由

    使用LabVIEW软件进行数据采集和信号处理的10大理由,很直得一看哦。
    发表于 09-03 17:27 4978次阅读

    大理由:XTREMIO 应用于数据库

    大理由:XTREMIO 应用于数据库
    发表于 12-25 00:25 0次下载

    Fibridge-DVP 代替 DVR的七大理由

    Fibridge-DVP 代替 DVR的七大理由
    发表于 12-26 22:06 0次下载

    关注C-RAN的五大理由

    业务的使用者都应该对C-RAN有所关心,为什么呢?这里给出五大理由。陈述这些理由之前,先来快速概括一下C-RAN的技术。
    发表于 11-17 16:14 2920次阅读

    自动焊接机器人的五大购买理由

    为什么购买自动焊接机器人?在科学技术飞速发展的当今社会,企业需要顺应时代发展的步伐,提高自身的自动化水平来实现转型升级,自动焊接机器人在焊接行业中的应用越来越广泛,逐渐代替了传统手动焊接,小编总结了自动焊接机器人购买的五大理由,我们一起往下看。
    发表于 01-15 15:54 633次阅读

    必须自动化SAN环境的5大理由

    电子发烧友网站提供《必须自动化SAN环境的5大理由.pdf》资料免费下载
    发表于 08-29 15:12 0次下载
    <b class='flag-5'>你</b>必须自动化SAN环境的5<b class='flag-5'>大理由</b>

    如何一个简单的装饰

    要的是,它 Python 中被装饰装饰后的方法长得更像装饰前的方法。 本篇文章不会过多的向你
    的头像 发表于 11-01 09:54 468次阅读
    如何<b class='flag-5'>写</b>一个简单的<b class='flag-5'>装饰</b><b class='flag-5'>器</b>

    选择精科睿进行 PCBA 代工代料有以下十大理由

    选择精科睿进行 PCBA 代工代料有以下十大理由
    的头像 发表于 11-06 10:21 126次阅读