简单理解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将IP地址在整型和字符串之间轻松转换
Mar 22 Python
python的Crypto模块实现AES加密实例代码
Jan 22 Python
Windows下的Jupyter Notebook 安装与自定义启动(图文详解)
Feb 21 Python
numpy.where() 用法详解
May 27 Python
python实现二级登陆菜单及安装过程
Jun 21 Python
django 控制页面跳转的例子
Aug 06 Python
Django使用Jinja2模板引擎的示例代码
Aug 09 Python
Python使用tkinter模块实现推箱子游戏
Oct 08 Python
Python 爬虫的原理
Jul 30 Python
Python 通过爬虫实现GitHub网页的模拟登录的示例代码
Aug 17 Python
详解java调用python的几种用法(看这篇就够了)
Dec 10 Python
python基础之类方法和静态方法
Oct 24 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操作SVN版本服务器类代码
2011/11/27 PHP
PHP字符过滤函数去除字符串最后一个逗号(rtrim)
2013/03/26 PHP
免费的ip数据库淘宝IP地址库简介和PHP调用实例
2014/04/08 PHP
thinkPHP3.2简单实现文件上传的方法
2016/05/16 PHP
深入理解JavaScript定时机制
2010/10/29 Javascript
js 实现css风格选择器(压缩后2KB)
2012/01/12 Javascript
DWR实现模拟Google搜索效果实现原理及代码
2013/01/30 Javascript
javascript中全局对象的parseInt()方法使用介绍
2013/12/19 Javascript
浅谈Sticky组件的改进实现
2016/03/22 Javascript
Node.js中Bootstrap-table的两种分页的实现方法
2017/09/18 Javascript
React通过父组件传递类名给子组件的实现方法
2017/11/13 Javascript
js/jQuery实现全选效果
2019/06/17 jQuery
layui动态渲染生成select的option值方法
2019/09/23 Javascript
elementUI同一页面展示多个Dialog的实现
2020/11/19 Javascript
[03:55]2016国际邀请赛中国区预选赛首日TOP10精彩集锦
2016/06/27 DOTA
详解Python使用simplejson模块解析JSON的方法
2016/03/24 Python
详解Python中heapq模块的用法
2016/06/28 Python
快速了解Python相对导入
2018/01/12 Python
对python for 文件指定行读写操作详解
2018/12/29 Python
python实现批量处理将图片粘贴到另一张图片上并保存
2019/12/12 Python
通过实例学习Python Excel操作
2020/01/06 Python
Python中的sys.stdout.write实现打印刷新功能
2020/02/21 Python
解决Python3.7.0 SSL低版本导致Pip无法使用问题
2020/09/03 Python
专门经营化妆刷的美国彩妆品牌:Sigma Beauty
2017/09/11 全球购物
中国跨境电子商务网站:NewFrog
2018/03/10 全球购物
新英格兰最大的特色礼品连锁店:The Paper Store
2018/07/23 全球购物
Linux如何压缩可执行文件
2013/10/21 面试题
现代化办公人员工作的自我评价
2013/10/16 职场文书
模具设计与制造专业应届生求职信
2013/10/18 职场文书
广告学专业自荐信范文
2014/02/24 职场文书
2014年教师节寄语
2014/04/03 职场文书
电大奖学金获奖感言
2014/08/14 职场文书
消防验收申请报告
2015/05/15 职场文书
昆虫记读书笔记
2015/06/26 职场文书
小学一年级语文教学反思
2016/03/03 职场文书
Feign调用传输文件异常的解决
2021/06/24 Java/Android