The only constraint on the result of a decorator is that it be callable, so it can
properly replace the decorated function.

decorator唯一限制是它必须是callable的,所以如果class作为decorator必须实现__call__方法使其成为callable的对象,而函数本身就是callable的。

用class做decorator

 1 class my_decorator(object): 2     def __init__(self, f): 3         print("inside my_decorator.__init__()") 4         f() # Prove that function definition has completed 5     def __call__(self): 6         print("inside my_decorator.__call__()") 7 @my_decorator 8 def aFunction(): 9     print("inside aFunction()")10 print("Finished decorating aFunction()")11 aFunction()

输出:

inside my_decorator.__init__()inside aFunction()Finished decorating aFunction()inside my_decorator.__call__()

如何解释这个输出,关键在于decorator程序的阅读要从程序执行顺序来理解,把decorator当成一次函数调用。

当程序从上至下执行到第7行时,my_decorator开始初始化,它以aFunction作为参数,传入__init__()执行,然后__call__将原函数替换,执行第10行代码,最后调用aFunction,因为这时原函数调用时,调用的是decorator替换后的callable对象,也就是__call__方法,所以执行的实际上是__call__。

函数作为decorator

 1 def entry_exit(f): 2     def new_f(): 3         print("Entering", f.__name__) 4         f() 5         print("Exited", f.__name__) 6     return new_f 7  8 @entry_exit 9 def func1():10     print("inside func1()")11     12 @entry_exit13 def func2():14     print("inside func2()")15     16 func1()17 func2()

同样,程序执行到第8行,调用entry_exit将func1当参数传入执行,返回new_f替换原函数,对func2同样处理,最后调用func1和func2时实际上调用的就是替换了以后的函数。

所以decorator从根本上是函数指针的替换,用一个callable的对象替换原来的函数。

转载于:https://www.cnblogs.com/babykick/archive/2012/03/05/2380855.html

python之decorator理解相关推荐

  1. 关于Python多线程的理解

    多线程和多进程是什么自行google补脑 对于python 多线程的理解,我花了很长时间,搜索的大部份文章都不够通俗易懂.所以,这里力图用简单的例子,让你对多线程有个初步的认识. 单线程 在好些年前的 ...

  2. python class 是否存在某个变量_一文抵十课,考验你的Python变量是否理解透彻了

    变量是编程的基础概念,Python 的变量也看似很简单,但是如果理解不当,生搬硬套,可能会遇到一些麻烦. 下面用 10 个代码示例展示 Python 的 变量 本质. 快来看看你对 Python 的变 ...

  3. python装饰器功能是冒泡排序怎么做_传说中Python最难理解的点|看这完篇就够了(装饰器)...

    https://mp.weixin.qq.com/s/B6pEZLrayqzJfMtLqiAfpQ 1.什么是装饰器 网上有人是这么评价装饰器的,我觉得写的很有趣,比喻的很形象 每个人都有的内裤主要是 ...

  4. python args kwargs 理解_*args和**kwargs在python中的作用

    我发现PYTHON新手在理解*args和**kwargs这两个魔法变量的时候有些困难.他们到底是什么呢? 首先,我先告诉大家一件事情,完整地写*args和**kwargs是不必要的,我们可以只写*和* ...

  5. python中类怎么理解_Python中的列表理解

    python中类怎么理解 In order to create a list, a most obvious and remembered solution is to use a for-loop. ...

  6. Python+OpenCV:理解K-Means聚类(K-Means Clustering)

    Python+OpenCV:理解K-Means聚类(K-Means Clustering) 理论 We will deal this with an example which is commonly ...

  7. Python+OpenCV:理解支持向量机(SVM)

    Python+OpenCV:理解支持向量机(SVM) 理论 线性可分数据(Linearly Separable Data) Consider the image below which has two ...

  8. Python+OpenCV:理解k近邻(kNN)算法(k-Nearest Neighbour (kNN) algorithm)

    Python+OpenCV:理解k近邻(kNN)算法(k-Nearest Neighbour (kNN) algorithm) 理论 kNN is one of the simplest classi ...

  9. python数据采集仪_数据采集卡支持python么深入理解Python生成器(Generator)

    我们可以通过列表生成式简单直接地创建一个列表,但是受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,而且如果我们仅仅需要访问前面几个元素,那后面绝大多 ...

最新文章

  1. Linux用户必须知道的常用终端快捷键
  2. 详解 CQRS 架构模式
  3. 机器人(机械臂)动力学建模方法(Newton-Euler equation)
  4. Qt5 中 关于Widget Mapper的简单应用
  5. 圆锥破碎机常见故障_圆锥破碎机飞车危害大! 7种原因早知道早预防
  6. Python每日一练(1):计算文件夹内各个文章中出现次数最多的单词
  7. Java基础学习总结(65)——Java中的String,StringBuilder和StringBuffer比较
  8. iOS工作中的经验总结—马甲包审核以及常见审核问题!!!(干货)
  9. 简单java游戏代码_Java经典小游戏——贪吃蛇简单实现(附源码)
  10. mysql事务的ACID原理
  11. 百度大脑开放日走进厦门 全面解析AI如何赋能企业服务智能化
  12. QQ被盗的自救、事故分析
  13. 2015移动技术白皮书
  14. 前端微服务化解决方案
  15. I.MX8M mini物联网开发板框架及屏幕接口详解
  16. 核心人才的管理方式(领导者必读)
  17. 通过搜狗抓取微信公众号--------破解url
  18. 专业有效的PDF转换成PPT转换器
  19. 京东 618:如何配合业务打造 JDReact 三端融合开发平台?
  20. 4G DTU 透传模块简单使用方法

热门文章

  1. ROS学习笔记12(用Python写一个简单的消息发布和消息订阅)
  2. pythoncsv数据类型_pandas读取CSV文件时查看修改各列的数据类型格式
  3. 2018-携程-春招题
  4. Java中抽象类和接口的区别(来源二,原始来源不明确)
  5. 不小心合并了icloud通讯录_苹果手机通讯录突然不见了如何恢复呢?
  6. kaggle实战_3模型分析与模型融合
  7. DeFi协议ValueDeFi疑似再次遭到攻击
  8. Gemini创始人:如果我是GameStop CEO 接下来我会买BTC
  9. Python之Django之views中视图代码重复查询的优化
  10. MySQL数据库性能优化的关键参数(转)