简单理解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类参数self使用示例
Feb 17 Python
使用beaker让Facebook的Bottle框架支持session功能
Apr 23 Python
详解Python中映射类型的内建函数和工厂函数
Aug 19 Python
在Django同1个页面中的多表单处理详解
Jan 25 Python
Python使用QRCode模块生成二维码实例详解
Jun 14 Python
Python实现的生产者、消费者问题完整实例
May 30 Python
Python干货:分享Python绘制六种可视化图表
Aug 27 Python
对Python协程之异步同步的区别详解
Feb 19 Python
python判断自身是否正在运行的方法
Aug 08 Python
将python安装信息加入注册表的示例
Nov 20 Python
关于python中plt.hist参数的使用详解
Nov 28 Python
pandas 操作 Excel操作总结
Mar 31 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 float不四舍五入截取浮点型字符串方法总结
2013/10/28 PHP
PHP实现的简单分页类及用法示例
2016/05/06 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
PHP设计模式入门之状态模式原理与实现方法分析
2020/04/26 PHP
List Information About the Binary Files Used by an Application
2007/06/18 Javascript
JS高级笔记
2011/07/13 Javascript
Select标签下拉列表二级联动级联实例代码
2014/02/07 Javascript
JS中Location使用详解
2015/05/12 Javascript
微信小程序 开发之顶部导航栏实例代码
2017/02/23 Javascript
基于LayUI实现前端分页功能的方法
2017/07/22 Javascript
详解在vue-cli中引用jQuery、bootstrap以及使用sass、less编写css
2017/11/08 jQuery
在vue项目中,使用axios跨域处理
2018/03/07 Javascript
angular5 httpclient的示例实战
2018/03/12 Javascript
详解Angular6学习笔记之主从组件
2018/09/05 Javascript
微信小程序实现搜索功能并跳转搜索结果页面
2019/05/18 Javascript
浅谈layui 数据表格前后台传值的问题
2019/09/12 Javascript
[01:19]2014DOTA2国际邀请赛 采访TITAN战队ohaiyo 能赢DK很幸运
2014/07/12 DOTA
python之import机制详解
2014/07/03 Python
python中os操作文件及文件路径实例汇总
2015/01/15 Python
Python编程中装饰器的使用示例解析
2016/06/20 Python
TF-IDF与余弦相似性的应用(一) 自动提取关键词
2017/12/21 Python
快速了解Python相对导入
2018/01/12 Python
使用Python和xlwt向Excel文件中写入中文的实例
2018/04/21 Python
Python实现12306火车票抢票系统
2019/07/04 Python
Django 通过JS实现ajax过程详解
2019/07/30 Python
python实现文件批量编码转换及注意事项
2019/10/14 Python
Python递归实现打印多重列表代码
2020/02/27 Python
HTML5是否真的可以取代Flash
2010/02/10 HTML / CSS
乌克兰电子产品和家用电器购物网站:TOUCH
2019/08/09 全球购物
大学生求职简历的自我评价
2013/10/14 职场文书
大学生个人实习的自我评价
2014/02/15 职场文书
2014迎新年晚会策划方案
2014/02/23 职场文书
医院保洁员管理制度
2015/08/05 职场文书
解决golang 关于全局变量的坑
2021/05/06 Golang
MySQL索引 高效获取数据的数据结构
2022/05/02 MySQL
Win11如何默认打开软件界面最大化?Win11默认打开软件界面最大化的方法
2022/07/15 数码科技