简单理解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 分析Nginx访问日志并保存到MySQL数据库实例
Mar 13 Python
Python字符串和文件操作常用函数分析
Apr 08 Python
Python类属性的延迟计算
Oct 22 Python
git使用.gitignore设置不生效或不起作用问题的解决方法
Jun 01 Python
python在线编译器的简单原理及简单实现代码
Feb 02 Python
python进行TCP端口扫描的实现
Dec 21 Python
Python实现的拉格朗日插值法示例
Jan 08 Python
python实现基于朴素贝叶斯的垃圾分类算法
Jul 09 Python
pytorch masked_fill报错的解决
Feb 18 Python
Python自定义sorted排序实现方法详解
Sep 18 Python
Sublime Text3最新激活注册码分享适用2020最新版 亲测可用
Nov 12 Python
Python中logging日志的四个等级和使用
Nov 17 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将数据导入到Foxmail的实现代码
2010/09/05 PHP
snoopy 强大的PHP采集类使用实例代码
2010/12/09 PHP
php利用cookie实现访问次数统计代码
2011/05/19 PHP
PHP获取文件行数的方法
2015/06/10 PHP
浅析PHP中Session可能会引起并发问题
2015/07/23 PHP
利用PHP抓取百度阅读的方法示例
2016/12/18 PHP
JS BASE64编码 window.atob(), window.btoa()
2021/03/09 Javascript
分析Node.js connect ECONNREFUSED错误
2013/04/09 Javascript
javascript中数组的concat()方法使用介绍
2013/12/18 Javascript
jquery设置text的值示例(设置文本框 DIV 表单值)
2014/01/06 Javascript
js 去除字符串第一位逗号的方法
2014/06/07 Javascript
javascript中Date对象的getDay方法使用指南
2014/12/22 Javascript
Javascript之BOM(window对象)详解
2016/05/25 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
2016/12/20 Javascript
Angularjs实现搜索关键字高亮显示效果
2017/01/17 Javascript
老生常谈js-react组件生命周期
2017/05/02 Javascript
JS开发常用工具函数(小结)
2019/07/04 Javascript
微信小程序 扭蛋抽奖机css3动画实现详解
2019/07/19 Javascript
TensorFlow用expand_dim()来增加维度的方法
2018/07/26 Python
pandas 空的dataframe 插入列名的示例
2018/10/30 Python
Python3自动签到 定时任务 判断节假日的实例
2018/11/13 Python
python TK库简单应用(实时显示子进程输出)
2019/10/29 Python
Python统计文本词汇出现次数的实例代码
2020/02/27 Python
可视化pytorch 模型中不同BN层的running mean曲线实例
2020/06/24 Python
Kidsroom台湾:来自德国的婴儿用品
2017/12/11 全球购物
俄罗斯儿童和青少年服装、鞋子及配件的在线商店:Orby
2020/02/20 全球购物
《画杨桃》教学反思
2014/04/13 职场文书
小学生操行评语
2014/04/22 职场文书
滴水洞导游词
2015/02/10 职场文书
2015年远程教育工作总结
2015/05/20 职场文书
2016年国庆节新闻稿范文
2015/11/25 职场文书
优秀大学生申请书
2019/06/24 职场文书
2019最新版股权转让及委托持股协议书范本
2019/08/07 职场文书
导游词之青岛崂山
2019/12/27 职场文书
pandas DataFrame.shift()函数的具体使用
2021/05/24 Python
php修改word的实例方法
2021/11/17 PHP