简单理解Python中的装饰器


Posted in Python onJuly 31, 2015

Python的装饰器可以实现在代码运行期间修改函数的上下文, 即可以定义函数在执行之前进行何种操作和函数执行后进行何种操作, 而函数本身并没有任何的改变。

首先, 我们先定义一个函数, 这个函数可以输出我的个人昵称:

def my_name():
  print "Yi_Zhi_Yu"
my_name() # Yi_Zhi_Yu

那假如我需要在个人昵称输出前, 在输出我的个人uid呢, 当然, 要求是不改动现有的my_name函数, 这个时候就可以使用装饰器了

首先, 装饰器也是个函数, 其次, 他需要接受一个参数,该参数表示了要被装饰的函数(即my_name):

def my_info(func):
  def wrapper(*args, **params):
    print 218
    return func(*args, **params)
  return wrapper

然后与相应的被装饰函数关联起来的方法就是使用@my_info写在被装饰函数的前面

@my_info
def my_name():
  print "Yi_Zhi_Yu"

最后, 在执行my_name的时候, 就能既输出我的uid, 又能输出我的昵称了

my_name()
#218
#Yi_Zhi_Yu

在上面, 最让我们疑惑的是装饰器函数定义里面的wrapper函数, 装饰器本身返回的是wrapper函数的定义, 而wrapper中则定义了对被装饰函数(my_name)的调用, func表示的就是被装饰函数, 说白了, 装饰器只是把某个不得改动的函数(a)放到另一个函数(b)中, 在b里面调用a, 在调用前后就可以做所谓的看起来像装饰的工作了。
my_info的最终返回的wrapper函数的定义, 并不是执行结果,只有当wrapper真正执行的时候, 才会真正的执行my_name方法, 这就是闭包时所说的内容。
wrapper中的参数, 实际上则是传递给func(实际上是my_name)的参数

因为装饰器也是个函数, 那么装饰器自己的能不能有参数传递呢。可以, 不过需要定义一个更高阶的函数, 也就是外面还要套一层函数, 比如, 我还要输出我的自定义的一个信息,需要传递参数

def c_info(text):
  def my_info(func):
    def wrapper(*args, **params):
      print text
      print 218
      return func(*args, **params)
    return wrapper
  return my_info
#使用装饰器

@c_info("Tony")
 def my_name():
  print "Yi_Zhi_Yu"

 my_name()
 #Tony
 #218
 #Yi_Zhi_Yu

与前面的那个装饰器相比, 仅仅是多了个外层, 内层也仅仅是增加了对外层传入参数(text)的调用

总而言之, Python在函数定义中支持了对oop思想中的装饰器的实现, 其本质也只是使用了闭包的思路, 延迟调用, 并在调用前后增加自己的其他实现内容

Ps: 以上皆为学习笔记, 附带自己的理解, 难免有偏差, 如有发现纰漏, 还望指正

Python 相关文章推荐
Python函数嵌套实例
Sep 23 Python
python文本数据相似度的度量
Mar 12 Python
Django + Uwsgi + Nginx 实现生产环境部署的方法
Jun 20 Python
python 读取文件并替换字段的实例
Jul 12 Python
python3.5安装python3-tk详解
Apr 26 Python
python实现比对美团接口返回数据和本地mongo数据是否一致示例
Aug 09 Python
Python列表元素常见操作简单示例
Oct 25 Python
Python手绘可视化工具cutecharts使用实例
Dec 05 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
Feb 10 Python
详解使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)
Apr 01 Python
Python实现简单的猜单词小游戏
Oct 28 Python
解决Pyinstaller打包软件失败的一个坑
Mar 04 Python
python简单分割文件的方法
Jul 30 #Python
Python读取网页内容的方法
Jul 30 #Python
python查看FTP是否能连接成功的方法
Jul 30 #Python
python如何实现excel数据添加到mongodb
Jul 30 #Python
python学习之第三方包安装方法(两种方法)
Jul 30 #Python
Python实现的Excel文件读写类
Jul 30 #Python
Djang中静态文件配置方法
Jul 30 #Python
You might like
预告映像公开!第1章续篇剧场版动画《Princess Principal Crown Handler》4月10日上映!
2020/03/06 日漫
PHP实现求解最长公共子串问题的方法
2017/11/17 PHP
PHP实现的curl批量请求操作示例
2018/06/06 PHP
JavaScript与函数式编程解释
2007/04/27 Javascript
javascript基本语法分析说明
2008/06/15 Javascript
jQuery 表单验证扩展代码(一)
2010/10/11 Javascript
Prototype源码浅析 Enumerable部分(二)
2012/01/18 Javascript
jQuery中filter()和find()的区别深入了解
2013/09/25 Javascript
javascript的渐进增强与平稳退化浅谈
2013/11/12 Javascript
如何书写高质量jQuery代码(使用jquery性能问题)
2014/06/30 Javascript
深入理解JavaScript系列(27):设计模式之建造者模式详解
2015/03/03 Javascript
JavaScript事件代理和委托详解
2016/04/08 Javascript
js/jq仿window文件夹框选操作插件
2017/03/08 Javascript
详解利用jsx写vue组件的方法示例
2017/07/17 Javascript
JS实现移动端触屏拖拽功能
2018/07/31 Javascript
详解Vue 项目中的几个实用组件(ts)
2019/10/29 Javascript
vue axios请求成功却进入catch的原因分析
2020/09/08 Javascript
[03:00]2018完美盛典_最佳英雄奖
2018/12/17 DOTA
python定时执行指定函数的方法
2015/05/27 Python
Python3一行代码实现图片文字识别的示例
2018/01/15 Python
python3第三方爬虫库BeautifulSoup4安装教程
2018/06/19 Python
Python udp网络程序实现发送、接收数据功能示例
2019/12/09 Python
Python pip安装模块提示错误解决方案
2020/05/22 Python
keras的ImageDataGenerator和flow()的用法说明
2020/07/03 Python
python/golang 删除链表中的元素
2020/09/14 Python
Python爬虫之Selenium鼠标事件的实现
2020/12/04 Python
浅谈Python xlwings 读取Excel文件的正确姿势
2021/02/26 Python
html5使用canvas绘制文字特效
2014/12/15 HTML / CSS
世界上最大的各式箱包网络零售店:eBag
2016/07/21 全球购物
医学生职业规划范文
2014/01/05 职场文书
关于学习的演讲稿
2014/05/10 职场文书
物资采购方案
2014/06/12 职场文书
信息管理与信息系统专业求职信
2014/06/21 职场文书
银行自荐信范文
2015/03/25 职场文书
创业计划书之餐饮馄饨店
2019/07/18 职场文书
java executor包参数处理功能 
2022/02/15 Java/Android