简单理解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 相关文章推荐
在Mac OS上部署Nginx和FastCGI以及Flask框架的教程
May 02 Python
Python中的条件判断语句基础学习教程
Feb 07 Python
详解Python编程中对Monkey Patch猴子补丁开发方式的运用
May 27 Python
详解python中executemany和序列的使用方法
Aug 12 Python
解决python 自动安装缺少模块的问题
Oct 22 Python
python利用多种方式来统计词频(单词个数)
May 27 Python
python超时重新请求解决方案
Oct 21 Python
python实现名片管理器的示例代码
Dec 17 Python
计算pytorch标准化(Normalize)所需要数据集的均值和方差实例
Jan 15 Python
Python使用shutil模块实现文件拷贝
Jul 31 Python
python析构函数用法及注意事项
Jun 22 Python
Python实现猜拳与猜数字游戏的方法详解
Apr 06 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
2020年4月放送!《Princess Connect Re:Dive》制作组 & 角色声优公开!
2020/03/06 日漫
php 购物车完整实现代码
2014/06/05 PHP
smarty模板引擎中变量及变量修饰器用法实例
2015/01/22 PHP
Yii2语言国际化自动配置详解
2018/08/22 PHP
PHP序列化的四种实现方法与横向对比
2018/11/29 PHP
关于恒等于(===)和非恒等于(!==)
2007/08/20 Javascript
js三种排序算法分享
2012/08/16 Javascript
form表单只提交数据而不进行页面跳转的解决方案
2013/09/18 Javascript
js中for in语句的用法讲解
2015/04/24 Javascript
js中通过getElementsByName访问name集合对象的方法
2016/10/31 Javascript
自学实现angularjs依赖注入
2016/12/20 Javascript
清除输入框内的空格
2016/12/21 Javascript
微信小程序 页面传值详解
2017/03/10 Javascript
jquery.flot.js简单绘制折线图用法示例
2017/03/13 Javascript
JS排序之选择排序详解
2017/04/08 Javascript
详解如何在React组件“外”使用父组件的Props
2018/01/12 Javascript
如何在vue中使用ts的示例代码
2018/02/28 Javascript
浅析Vue.js 中的条件渲染指令
2018/11/19 Javascript
vue项目首屏打开速度慢的解决方法
2019/03/31 Javascript
用JS实现选项卡
2020/03/23 Javascript
浅谈vue 多个变量同时赋相同值互相影响
2020/08/05 Javascript
Python 数据结构之旋转链表
2017/02/25 Python
python 简单备份文件脚本v1.0的实例
2017/11/06 Python
python机器学习理论与实战(一)K近邻法
2021/01/28 Python
Python使用zip合并相邻列表项的方法示例
2018/03/17 Python
启动Atom并运行python文件的步骤
2018/11/09 Python
Python Scapy随心所欲研究TCP协议栈
2018/11/20 Python
Python3对称加密算法AES、DES3实例详解
2018/12/06 Python
python将控制台输出保存至文件的方法
2019/01/07 Python
Python中base64与xml取值结合问题
2019/12/22 Python
Python使用tkinter实现小时钟效果
2021/02/22 Python
StudentUniverse英国:学生航班、酒店和旅游
2019/08/25 全球购物
工作失职检讨书范文
2014/01/16 职场文书
主题教育活动总结
2014/05/05 职场文书
2015年高考寄语或鼓励的话
2015/03/23 职场文书
C站最全Python标准库总结,你想要的都在这里
2021/07/03 Python