文档章节

python装饰器详解

刘地
 刘地
发布于 2017/01/06 19:20
字数 802
阅读 35
收藏 2

python的装饰器其实是一个语法糖,第一行是@跟着一个表达式;第二行必须以def或者class起始(亦即函数或者class的定义)。

python的装饰器,必须是可调用的对象,而且必须是可以以一个参数进行调用。注意,对返回参数的个数是不做限制的!

那么,python中有几种可调用对象呢?大致有四种:

1)函数对象,这个不用多说什么了吧;
2)类对象,我们生成类实例的时候,都是用类对象调用生成的;
3)类的三种方法:实例方法、类方法、静态方法;
4)如果类实现了`__call__`方法,则类的实例对象也是可调用的;

装饰器本质上就是一个语法糖,它等价于先定义了函数/类之后,将函数对象/类对象作为参数调用装饰器,然后将返回值赋给原本代表函数对象/类对象的变量。

事实上,只要装饰器能够成功执行,不管它如何处理的,python都不会报错。即使返回值不是同类的函数或者类对象,而是其它的什么东西,比如基本类型,乃至列表/元组都无所谓。

好了,我们现在差不多,就知道装饰器这玩意是一个多么自由的东西了。其实python里面n多东西都这么自由。

根据装饰器的输入和输出,我们可以将装饰器分成如下几类

1)吃进一个函数,吐出一个修饰过的函数。
    这是我们自己最常写的一种装饰器了,通常我们通过装饰器,来进行log、缓存、类型检验、错误捕捉等等。

2)吃进一个函数,返回一个class对象。
    这种情况比较罕见,至少我没有见过。

3)吃进一个函数,吐出一个class的实例。
    最典型的,比如property,它可以吃进一个函数,返回一个描述器的实例(注意返回的实例的身份肯定是类的属性)。staticmethod和classmethod也是一样的道理。
    还有一种情况,也就是返回一个实现了`__call__`方法的class对象的实例。这种相当于一个可更新环境的闭包,有时候挺有用。
    
4)吃进一个函数,吐出一个不可调用对象。
    基本上,这是起到一个提前计算的作用。比如说一个装饰器可以接受一个函数,然后预先计算出函数的返回值,然后直接将返回值赋给原本代表函数对象/类对象的变量。
    
5)吃进一个class对象,吐出一个函数。
    比如返回一个可以使用参数来返回该class对象的实例的函数,但同时也进行log、缓存、类型检验、错误捕捉等等。
    
6)吃进一个class对象,吐出一个class对象。
    和第一种类似,只不过是对class对象进行完善,比如functools.total_ordering,它就是可以完善class对象的比较运算的魔术方法。
    

© 著作权归作者所有

刘地
粉丝 101
博文 52
码字总数 69858
作品 1
朝阳
私信 提问
转载:唐磊的个人博客《python中decorator详解》【转注:深入浅出清晰明了】

转载请注明来源:唐磊的个人博客《python中decorator详解》 前面写python的AOP解决方案时提到了decorator,这篇文章就详细的来整理下python的装饰器——decorator。 python中的函数即objects...

laugh2last
2015/08/17
1K
0
设计模式之:理解 Python 中的装饰器

1、问题 文章先由stackoverflow上面的一个问题引起吧,如果使用如下的代码: @makebold @makeitalic def say(): return "Hello" 打印出如下的输出: <b><i>Hello<i></b> 你会怎么做?最后给出......

大数据之路
2013/07/22
1K
0
Python知识点:理解和使用装饰器 @decorator

我在我的个人博客“猿人学网站”和公众号“猿人学Python”上写Python教程,有兴趣的可以关注公众号和网站。 Python的装饰器(decorator)是一个很棒的机制,也是熟练运用Python的必杀技之一。...

呆木木人儿
03/12
1K
3
一份来自 StackOverflow 的最佳 Python 装饰器教程

(给Python开发者加星标,提升Python技能) 翻译:可乐,校对:艾凌风 发布:Python开发者(id:PythonCoder) 注意: 这是一篇 StackOverflow 上的问题回答,因为这个回答很棒,所以我把它存...

Python开发者
04/25
0
0
Python3 与 C# 扩展之~基础拓展

上次知识回顾:https://www.cnblogs.com/dotnetcrazy/p/9278573.html 代码裤子:https://github.com/lotapp/BaseCode 在线编程:https://mybinder.org/v2/gh/lotapp/BaseCode/master 在线预览......

鲲逸鹏
2018/07/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

java快递电子面单打印接口对接demo

之前的后天管理系统的电子面单打印使用的是灵通打单。 使用相对比较麻烦,需要到处Excel之后再导入,麻烦。 快递鸟有电子面单api,后台系统直接对接很是方便,不过也遇到了好些问题。 不难是...

程序的小猿
26分钟前
3
0
fasjtjson文档

https://github.com/alibaba/fastjson/wiki/JSONField

jirak
26分钟前
3
0
Mybatis中插入多条记录

Oracle数据库 实现方法 <insert id="saveWithdrawLog"> INSERT ALL INTO OSM_TRADE_DETAIL(SID,MBR_ID,USR_ID,TRADE_MONEY,TRADE_TYPE,TRADE_TIME,TRADE_WAY,PAY_ID) VALUES(#{si......

豫华商
27分钟前
3
0
Flink on YARN(下):常见问题与排查思路

作者:杨弢(搏远) Flink 支持 Standalone 独立部署和 YARN、Kubernetes、Mesos 等集群部署模式,其中 YARN 集群部署模式在国内的应用越来越广泛。Flink 社区将推出 Flink on YARN 应用解读...

开源中国小二
29分钟前
3
0
技术沙龙|京东云端到端多媒体关键技术揭秘

编者按:从带来更高编码效率、更好的用户体验的京享高清,到直播架构与网络演进优化,从而为用户带来更流畅的观看体验,以及运维系统的异常自动修复和高弹性的多媒体存储架构,一层一层展示出...

京东云技术新知
29分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部