简单理解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 相关文章推荐
linux系统使用python获取cpu信息脚本分享
Jan 15 Python
简单介绍Python中的try和finally和with方法
May 05 Python
Python 遍历列表里面序号和值的方法(三种)
Feb 17 Python
深入探究Django中的Session与Cookie
Jul 30 Python
python实现在pandas.DataFrame添加一行
Apr 04 Python
对python中Matplotlib的坐标轴的坐标区间的设定实例讲解
May 25 Python
Python pycharm 同时加载多个项目的方法
Jan 17 Python
Python 、Pycharm、Anaconda三者的区别与联系、安装过程及注意事项
Oct 11 Python
python手写均值滤波
Feb 19 Python
python中元组的用法整理
Jun 15 Python
Python实现快速大文件比较代码解析
Sep 04 Python
用Python进行websocket接口测试
Oct 16 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
PL-880隐藏功能
2021/03/01 无线电
PHP实现MVC开发得最简单的方法――模型
2007/04/10 PHP
php cookis创建实现代码
2009/03/16 PHP
PHP文章按日期(月日)SQL归档语句
2012/11/29 PHP
CI框架扩展系统核心类的方法分析
2016/05/23 PHP
超强多功能php绿色集成环境详解
2017/01/25 PHP
php + nginx项目中的权限详解
2017/05/23 PHP
利用laravel搭建一个迷你博客实战教程
2017/08/13 PHP
深入解析PHP底层机制及相关原理
2020/12/11 PHP
无阻塞加载脚本分析[全]
2011/01/20 Javascript
javascript闭包的高级使用方法实例
2013/07/04 Javascript
js 中的switch表达式使用示例
2020/06/03 Javascript
网站繁简切换的JS遇到页面卡死的解决方法
2014/03/12 Javascript
纯JavaScript手写图片轮播代码
2016/10/20 Javascript
JS前端加密算法示例
2016/12/22 Javascript
js图片加载效果实例代码(延迟加载+瀑布流加载)
2017/05/12 Javascript
详解vuex的简单使用
2018/03/12 Javascript
微信小程序实现登录注册tab切换效果
2020/12/29 Javascript
Vue路由前后端设计总结
2019/08/06 Javascript
vue+element-ui JYAdmin后台管理系统模板解析
2020/07/28 Javascript
[02:34]2016完美“圣”典风云人物:BurNIng专访
2016/12/10 DOTA
Python使用scrapy采集数据过程中放回下载过大页面的方法
2015/04/08 Python
Python的Flask框架中使用Flask-SQLAlchemy管理数据库的教程
2016/06/14 Python
Python多线程爬虫实战_爬取糗事百科段子的实例
2017/12/15 Python
Django为窗体加上防机器人的验证码功能过程解析
2019/08/14 Python
python实现人像动漫化的示例代码
2020/05/17 Python
Keras实现DenseNet结构操作
2020/07/06 Python
Pure Collection美国官网:来自英国羊绒专家的奢华羊绒
2017/11/19 全球购物
升职自荐书范文
2013/11/28 职场文书
求职信标题怎么写
2014/05/26 职场文书
大学生万能检讨书范例
2014/10/04 职场文书
湖南省党的群众路线教育实践活动总结会议新闻稿
2014/10/21 职场文书
罚站检讨书
2015/01/29 职场文书
2015年法院工作总结范文
2015/04/28 职场文书
毕业生登记表班级意见
2015/06/05 职场文书
mysql sock文件存储了什么信息
2022/07/15 MySQL