简单理解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多进程通信Queue、Pipe、Value、Array实例
Nov 21 Python
Python函数可变参数定义及其参数传递方式实例详解
May 25 Python
Python中使用插入排序算法的简单分析与代码示例
May 04 Python
对numpy 数组和矩阵的乘法的进一步理解
Apr 04 Python
Python实现自定义函数的5种常见形式分析
Jun 16 Python
Python实现简单的用户交互方法详解
Sep 25 Python
Python scipy的二维图像卷积运算与图像模糊处理操作示例
Sep 06 Python
Django 创建后台,配置sqlite3教程
Nov 18 Python
运行tensorflow python程序,限制对GPU和CPU的占用操作
Feb 06 Python
python向企业微信发送文字和图片消息的示例
Sep 28 Python
python3实现名片管理系统(控制台版)
Nov 29 Python
pytorch中的model.eval()和BN层的使用
May 22 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中计算字符串相似度的函数代码
2012/12/29 PHP
PHP实现动态柱状图改进版
2015/03/30 PHP
php中的常用魔术方法汇总
2016/02/14 PHP
IE Firefox 使用自定义标签的区别
2009/10/15 Javascript
新浪微博字数统计 textarea字数统计实现代码
2011/08/28 Javascript
jQuery仿Excel表格编辑功能的实现代码
2013/05/01 Javascript
jquery模拟SELECT下拉框取值效果
2013/10/23 Javascript
js正则表达exec与match的区别说明
2014/01/29 Javascript
JS判断移动端访问设备并加载对应CSS样式
2014/06/13 Javascript
全面了解JavaScirpt 的垃圾(garbage collection)回收机制
2016/07/11 Javascript
JavaScript对JSON数据进行排序和搜索
2017/07/24 Javascript
Vue+Flask实现简单的登录验证跳转的示例代码
2018/01/13 Javascript
使用vuex缓存数据并优化自己的vuex-cache
2018/05/30 Javascript
Vue全局分页组件的实现代码
2018/08/10 Javascript
layui 上传图片 返回图片地址的方法
2019/09/26 Javascript
[36:33]2018DOTA2亚洲邀请赛 4.3 突围赛 EG vs Newbee 第二场
2018/04/04 DOTA
如何运行Python程序的方法
2013/04/21 Python
解析Python中的__getitem__专有方法
2016/06/27 Python
HTML5实现WebSocket协议原理浅析
2014/07/07 HTML / CSS
Trip.com香港网站:Ctrip携程旗下,全球最大的网上旅游社之一
2016/08/01 全球购物
女性时尚网购:Chic Me
2019/07/30 全球购物
EMPHASIS艾斐诗官网:周生生旗下原创精品珠宝品牌
2020/12/17 全球购物
公司接待方案
2014/03/08 职场文书
办公自动化毕业生求职信
2014/03/09 职场文书
学习型党组织建设经验材料
2014/05/26 职场文书
歌唱比赛策划方案
2014/06/06 职场文书
小学生竞选班干部演讲稿(5篇)
2014/09/12 职场文书
护理见习报告范文
2014/11/03 职场文书
社区元宵节活动总结
2015/02/06 职场文书
银行优秀员工推荐信
2015/03/24 职场文书
观看焦裕禄观后感
2015/06/09 职场文书
退休欢送会主持词
2015/07/01 职场文书
值班管理制度范本
2015/08/06 职场文书
预备党员入党感想
2015/08/10 职场文书
Win11 Dev 预览版25174.1000发布 (附更新修复内容汇总)
2022/08/05 数码科技
python缺失值填充方法示例代码
2022/12/24 Python