资讯专栏INFORMATION COLUMN

流畅的 Python - 5. 装饰器与闭包

Markxu / 2318人阅读

摘要:看了这一章,发现原来是装饰器,又一新知识。期间,装饰器会做一些额外的工作。书中介绍了模块中的三个装饰器。另一个是,这个装饰器把函数结果保存了起来,避免传入相同参数时重复计算。叠放不奇怪,装饰器返回的就是函数或可调用对象。

在 Web 框架 Flask 中,最常看到的或许是以@app.route开头的那行代码。由于还是刚接触 Flask,所以对这种语法还不熟悉。看了这一章,发现原来是装饰器,又一新知识。

什么是装饰器?它是一个可调用对象,接受一个函数并返回一个函数或可调用对象。期间,装饰器会做一些额外的工作。

书上介绍了装饰器有两大特性,一个是「能把被装饰的函数替换成其他函数」,另一个是「装饰器在加载模块时立即执行」。常用的方式是把装饰器定义在一个模块中,返回的是内部新定义的函数。此外,需要注意的是导入时和运行时的区别。

之后的闭包,保证了内部函数代码的正确运行。什么是闭包?

闭包指延伸了作用域的函数,其中包含函数定义体中引用、但是不在定义体中定义的非全局变量。

闭包依旧是函数,只是其中包含了即非全部、也非本地变量的变量。这样的变量叫做自由变量(free variable)。当要改变自由变量时,自由变量会变成本地变量。关键字nonlocal可以保护自由变量。

书中介绍了functools模块中的三个装饰器。第一个是wraps,它能把相关属性从被装饰的函数中正确地复制到装饰器的内部函数中。

另一个是lru_cache,这个装饰器把函数结果保存了起来,避免传入相同参数时重复计算。使用它跟之前的例子有点不同:@functools.lru_cache(),因为它可以接受配置参数,即缓存结果的数目和是否把不同类型的结果分开保存。被lru_cache装饰的函数的所有参数必须是可散列的,因为它使用字典存储结果,键根据调用时传入的定位参数和关键字参数创建。

最后一个是singledispatch,被它装饰的函数会变成泛函数(generic function),类似 Lisp 中的 generic function。在 Java 的类中,类似于方法重载。

装饰器一个强大的能力就是支持叠放,另一个是参数化。叠放不奇怪,装饰器返回的就是函数或可调用对象。而参数化中,接受参数的装饰器叫做装饰器工厂函数,它返回的是一个装饰器,之后把它应用到要装饰的函数上。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41645.html

相关文章

  • 流畅python读书笔记-第七章-函数装饰器和闭包

    摘要:函数装饰器和闭包严格来说,装饰器只是语法糖。何时执行装饰器它们在被装饰的函数定义之后立即运行。装饰器突出了被装饰的函数的作用,还便于临时禁用某个促销策略只需把装饰器注释掉。 函数装饰器和闭包 严格来说,装饰器只是语法糖。如前所示,装饰器可以像常规的可调用对象那样调用,其参数是另一个函数。有时,这样做更方便,尤其是做元编程(在运行时改变程序的行为)时。 Python何时执行装饰器 它们在...

    Hydrogen 评论0 收藏0
  • 每天一个设计模式之装饰者模式

    摘要:作者按每天一个设计模式旨在初步领会设计模式的精髓,目前采用和两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式原文地址是每天一个设计模式之装饰者模式欢迎关注个人技术博客。 作者按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式...

    brianway 评论0 收藏0
  • 每天一个设计模式之装饰者模式

    摘要:作者按每天一个设计模式旨在初步领会设计模式的精髓,目前采用和两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式原文地址是每天一个设计模式之装饰者模式欢迎关注个人技术博客。 作者按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式...

    shleyZ 评论0 收藏0
  • 装饰器与元数据反射(2)属与类性装饰

    摘要:值得注意的是,的返回值复写了原始的构造函数,原因是类装饰器必须返回一个构造器函数。原始构造函数的原型被复制给的原型,以确保在创建一个的新实例时,操作符如愿以偿,具体原因可参考鄙人另一篇文章原型与对象。 上一篇文章中,我们讨论了TypeScript源码中关于方法装饰器的实现,搞明白了如下几个问题: 装饰器函数是如何被调用的? 装饰器函数参数是如何传入的? __decorate函数干了...

    Shisui 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<