简单上手Python中装饰器的使用


Posted in Python onJuly 12, 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思想中的装饰器的实现, 其本质也只是使用了闭包的思路, 延迟调用, 并在调用前后增加自己的其他实现内容

Python 相关文章推荐
Django在Win7下的安装及创建项目hello word简明教程
Jul 14 Python
python中使用序列的方法
Aug 03 Python
python通过文件头判断文件类型
Oct 30 Python
Python聚类算法之基本K均值实例详解
Nov 20 Python
利用Anaconda完美解决Python 2与python 3的共存问题
May 25 Python
浅析Python中return和finally共同挖的坑
Aug 18 Python
Python3使用PyQt5制作简单的画板/手写板实例
Oct 19 Python
itchat接口使用示例
Oct 23 Python
python正则表达式面试题解答
Apr 28 Python
python命令行解析之parse_known_args()函数和parse_args()使用区别介绍
Jan 24 Python
Python计算时间间隔(精确到微妙)的代码实例
Feb 26 Python
python调用其他文件函数或类的示例
Jul 16 Python
python比较两个列表大小的方法
Jul 11 #Python
python实现计算倒数的方法
Jul 11 #Python
python实现基本进制转换的方法
Jul 11 #Python
python计算圆周率pi的方法
Jul 11 #Python
python计算一个序列的平均值的方法
Jul 11 #Python
python修改字典内key对应值的方法
Jul 11 #Python
python字典基本操作实例分析
Jul 11 #Python
You might like
php实现以只读方式打开文件的方法
2015/03/16 PHP
PHP中in_array函数使用的问题与解决办法
2016/09/11 PHP
php测试kafka项目示例
2020/02/06 PHP
微信小程序页面间通信的5种方式
2017/03/31 Javascript
利用node.js本地搭建HTTP服务器
2017/04/19 Javascript
Angular.js中定时器循环的3种方法总结
2017/04/27 Javascript
在小程序Canvas中使用measureText的方法示例
2018/10/19 Javascript
详解NodeJs项目 CentOs linux服务器线上部署
2019/09/16 NodeJs
微信小程序组件生命周期的踩坑记录
2021/03/03 Javascript
[36:05]完美世界DOTA2联赛循环赛 Forest vs DM 第一场 11.06
2020/11/06 DOTA
Python函数式编程指南(二):从函数开始
2015/06/24 Python
在Django的session中使用User对象的方法
2015/07/23 Python
python一键升级所有pip package的方法
2017/01/16 Python
Python定时器实例代码
2017/11/01 Python
tensorflow输出权重值和偏差的方法
2018/02/10 Python
Python递归实现汉诺塔算法示例
2018/03/19 Python
numpy找出array中的最大值,最小值实例
2018/04/03 Python
Python将列表数据写入文件(txt, csv,excel)
2019/04/03 Python
Python利用pandas处理Excel数据的应用详解
2019/06/18 Python
python如何获取列表中每个元素的下标位置
2019/07/01 Python
使用OpenCV实现仿射变换—平移功能
2019/08/29 Python
Python 实现顺序高斯消元法示例
2019/12/09 Python
keras模型可视化,层可视化及kernel可视化实例
2020/01/24 Python
植物选择:Botanic Choice
2017/02/15 全球购物
美国现代家具购物网站:LexMod
2019/01/09 全球购物
德国户外装备、登山运动和攀岩商店:tapir store
2020/02/12 全球购物
澳大利亚最受欢迎的女士度假服装:Kabana Shop
2020/10/10 全球购物
实习销售业务员自我鉴定
2013/09/21 职场文书
2015年大学社团工作总结
2015/04/09 职场文书
职场新人知识:如何制定一份合理的工作计划?
2019/09/11 职场文书
导游词之大雁塔景区
2019/09/17 职场文书
Python selenium模拟网页点击爬虫交管12123违章数据
2021/05/26 Python
详解gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
2021/11/27 Vue.js
聊聊Python String型列表求最值的问题
2022/01/18 Python
Pandas 数据编码的十种方法
2022/04/20 Python
win server2012 r2服务器共享文件夹如何设置
2022/06/21 Servers