简单理解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实现数通设备tftp备份配置文件示例
Apr 02 Python
python装饰器decorator介绍
Nov 21 Python
Python使用scrapy采集时伪装成HTTP/1.1的方法
Apr 08 Python
python实现生命游戏的示例代码(Game of Life)
Jan 24 Python
Python动刷新抢12306火车票的代码(附源码)
Jan 24 Python
基于python指定包的安装路径方法
Oct 27 Python
Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】
Jan 05 Python
Python一键查找iOS项目中未使用的图片、音频、视频资源
Aug 12 Python
如何在django中添加日志功能
Feb 06 Python
在python里使用await关键字来等另外一个协程的实例
May 04 Python
浅谈keras中自定义二分类任务评价指标metrics的方法以及代码
Jun 11 Python
python 检测图片是否有马赛克
Dec 01 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
PHP使用GIFEncoder类处理gif图片实例
2014/07/01 PHP
php输入数据统一类实例
2015/02/23 PHP
php实现删除空目录的方法
2015/03/16 PHP
ubuntu下配置nginx+php+mysql详解
2015/09/10 PHP
基于jQuery的可以控制左右滚动及自动滚动效果的代码
2010/07/25 Javascript
利用JQuery的load函数动态加载其它页面的内容的实现代码
2010/12/14 Javascript
js实现图片轮换效果代码
2013/04/16 Javascript
使用JSON.parse将json字符串转换成json对象的时候会出错
2014/09/04 Javascript
JS输入用户名自动显示邮箱后缀列表的方法
2015/01/27 Javascript
PHP和NodeJs开发的应用如何共用Session
2015/04/16 NodeJs
jQuery简单注册和禁用全局事件的方法
2016/07/25 Javascript
vue实现底部菜单功能
2018/07/24 Javascript
详解js根据百度地图提供经纬度计算两点距离
2019/05/13 Javascript
vue中keep-alive内置组件缓存的实例代码
2020/04/16 Javascript
详解Python的Django框架中的templates设置
2015/05/11 Python
Python基于checksum计算文件是否相同的方法
2015/07/09 Python
django 创建过滤器的实例详解
2017/08/14 Python
利用python如何处理nc数据详解
2018/05/23 Python
Python返回数组/List长度的实例
2018/06/23 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
2019/02/08 Python
使用pandas的box_plot去除异常值
2019/12/10 Python
python使用docx模块读写docx文件的方法与docx模块常用方法详解
2020/02/17 Python
python自动下载图片的方法示例
2020/03/25 Python
PyQt5的相对布局管理的实现
2020/08/07 Python
皇马官方商城:Real Madrid Store
2016/09/02 全球购物
惠而浦美国官网:Whirlpool.com
2021/01/19 全球购物
三问三解心得体会
2014/09/05 职场文书
司机工作自我鉴定
2014/09/19 职场文书
合作协议书范本
2014/10/25 职场文书
被告答辩状范文
2015/05/22 职场文书
毕业答辩开场白范文
2015/05/27 职场文书
2015年终个人政治思想工作总结
2015/11/24 职场文书
JavaScript实现班级抽签小程序
2021/05/19 Javascript
SQL IDENTITY_INSERT作用案例详解
2021/08/23 MySQL
PO模式在selenium自动化测试框架的优势
2022/03/20 Python
Nginx+Tomcat负载均衡多实例详解
2022/04/11 Servers