简单理解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函数返回值实例分析
Jun 08 Python
Python的包管理器pip更换软件源的方法详解
Jun 20 Python
Python列表list内建函数用法实例分析【insert、remove、index、pop等】
Jul 24 Python
Python爬虫实现百度图片自动下载
Feb 04 Python
python3写的简单本地文件上传服务器实例
Jun 04 Python
Python实现的简单计算器功能详解
Aug 25 Python
在mac下查找python包存放路径site-packages的实现方法
Nov 06 Python
使用urllib库的urlretrieve()方法下载网络文件到本地的方法
Dec 19 Python
python实现人工智能Ai抠图功能
Sep 05 Python
利用pyecharts读取csv并进行数据统计可视化的实现
Apr 17 Python
Python实现汇率转换操作
May 03 Python
Python约瑟夫生者死者小游戏实例讲解
Jan 04 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
美图秀秀web开放平台--PHP流式上传和表单上传示例分享
2014/06/22 PHP
PHP使用strtotime计算两个给定日期之间天数的方法
2015/03/18 PHP
PDO::errorCode讲解
2019/01/28 PHP
JavaScript 关键字屏蔽实现函数
2009/08/02 Javascript
(jQuery,mootools,dojo)使用适合自己的编程别名命名
2010/09/14 Javascript
关于firefox的ElementTraversal 接口 使用说明
2010/11/11 Javascript
JavaScript的setAttribute兼容性问题解决方法
2013/11/11 Javascript
js图片延迟技术一般的思路与示例
2014/03/20 Javascript
一些老手都不一定知道的JavaScript技巧
2014/05/06 Javascript
js滑动提示效果代码分享
2016/03/10 Javascript
原生JS仿QQ阅读点击展开、收起效果
2017/03/08 Javascript
jQuery访问浏览器本地存储cookie、localStorage和sessionStorage的基本用法
2017/10/20 jQuery
Bootstrap栅格系统的使用详解
2017/10/30 Javascript
AngularJS2 与 D3.js集成实现自定义可视化的方法
2017/12/01 Javascript
React Hooks 实现和由来以及解决的问题详解
2020/01/17 Javascript
python使用reportlab实现图片转换成pdf的方法
2015/05/22 Python
python创建临时文件夹的方法
2015/07/06 Python
浅谈python新手中常见的疑惑及解答
2016/06/14 Python
Python3网络爬虫中的requests高级用法详解
2019/06/18 Python
python中 * 的用法详解
2019/07/10 Python
Tensorflow安装问题: Could not find a version that satisfies the requirement tensorflow
2020/04/20 Python
用python实现前向分词最大匹配算法的示例代码
2020/08/06 Python
python编写实现抽奖器
2020/09/10 Python
Pycharm同步远程服务器调试的方法步骤
2020/11/04 Python
Dr.Jart+美国官网:韩国药妆品牌
2019/01/18 全球购物
《一株紫丁香》教学反思
2014/02/19 职场文书
演讲主持词
2014/03/18 职场文书
历史学专业求职信
2014/06/19 职场文书
市级绿色学校申报材料
2014/08/25 职场文书
狼牙山五壮士观后感
2015/06/09 职场文书
收入证明怎么写
2015/06/12 职场文书
学者《孟子》名人名言
2019/08/09 职场文书
手把手教你用SpringBoot将文件打包成zip存放或导出
2021/06/11 Java/Android
Java实现多文件上传功能
2021/06/30 Java/Android
SQL Server数据库基本概念、组成、常用对象与约束
2022/03/20 SQL Server
Python可视化动图组件ipyvizzu绘制惊艳的可视化动图
2022/04/21 Python