基于Python 装饰器装饰类中的方法实例


Posted in Python onApril 21, 2018

title: Python 装饰器装饰类中的方法

comments: true
date: 2017-04-17 20:44:31
tags: ['Python', 'Decorate']
category: ['Python']
---

目前在中文网上能搜索到的绝大部分关于装饰器的教程,都在讲如何装饰一个普通的函数。本文介绍如何使用Python的装饰器装饰一个类的方法,同时在装饰器函数中调用类里面的其他方法。本文以捕获一个方法的异常为例来进行说明。

有一个类Test, 它的结构如下:

class Test(object):
 def __init__(self):
  pass
 def revive(self):
  print('revive from exception.')
  # do something to restore
 def read_value(self):
  print('here I will do something.')
  # do something.

在类中有一个方法read_value(),这个方法在多个地方被调用。由于某些原因,方法read_value有可能随机抛出Exception导致程序崩溃。所以需要对整个方法做try ... except处理。最丑陋的做法如下面的代码所示:

class Test(object):
 def __init__(self):
  pass
 def revive(self):
  print('revive from exception.')
  # do something to restore
 def read_value(self):
  try:
   print('here I will do something.')
   # do something.
  except Exception as e:
   print(f'exception {e} raised, parse exception.')
   # do other thing.
   self.revive()

这样写虽然可以解决问题,但是代码不Pythonic。

使用装饰器来解决这个问题,装饰器函数应该写在类里面还是类外面呢?答案是,写在类外面。那么既然写在类外面,如何调用这个类的其他方法呢?

首先写出一个最常见的处理异常的装饰器:

def catch_exception(origin_func):
 def wrapper(*args, **kwargs):
  try:
   u = origin_func(*args, **kwargs)
   return u
  except Exception:
   return 'an Exception raised.'
 return wrapper
class Test(object):
 def __init__(self):
  pass
 def revive(self):
  print('revive from exception.')
  # do something to restore
 @catch_exception
 def read_value(self):
  print('here I will do something.')
  # do something.

这种写法,确实可以捕获到origin_func()的异常,但是如果在发生异常的时候,需要调用类里面的另一个方法来处理异常,这又应该怎么办?答案是给wrapper增加一个参数:self.

代码变为如下形式:

def catch_exception(origin_func):
 def wrapper(self, *args, **kwargs):
  try:
   u = origin_func(self, *args, **kwargs)
   return u
  except Exception:
   self.revive() #不用顾虑,直接调用原来的类的方法
   return 'an Exception raised.'
 return wrapper
class Test(object):
 def __init__(self):
  pass
 def revive(self):
  print('revive from exception.')
  # do something to restore
 @catch_exception
 def read_value(self):
  print('here I will do something.')
  # do something.

只需要修改装饰器定义的部分,使用装饰器的地方完全不需要做修改。

下图为正常运行时的运行结果:

基于Python 装饰器装饰类中的方法实例

下图为发生异常以后捕获并处理异常:

基于Python 装饰器装饰类中的方法实例

通过添加一个self参数,类外面的装饰器就可以直接使用类里面的各种方法,也可以直接使用类的属性。

以上这篇基于Python 装饰器装饰类中的方法实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python和php通信乱码问题解决方法
Apr 15 Python
简单理解Python中的装饰器
Jul 31 Python
Python进阶学习之特殊方法实例详析
Dec 01 Python
Python向Excel中插入图片的简单实现方法
Apr 24 Python
python批量查询、汉字去重处理CSV文件
May 31 Python
python基于C/S模式实现聊天室功能
Jan 09 Python
使用TensorFlow实现简单线性回归模型
Jul 19 Python
安装Pycharm2019以及配置anconda教程的方法步骤
Nov 11 Python
python单例设计模式实现解析
Jan 07 Python
python实现飞船大战
Apr 24 Python
Matplotlib 折线图plot()所有用法详解
Jul 28 Python
C站最全Python标准库总结,你想要的都在这里
Jul 03 Python
使用python装饰器计算函数运行时间的实例
Apr 21 #Python
Python实现针对给定字符串寻找最长非重复子串的方法
Apr 21 #Python
Python 实现一行输入多个值的方法
Apr 21 #Python
Python实现接受任意个数参数的函数方法
Apr 21 #Python
深入分析python数据挖掘 Json结构分析
Apr 21 #Python
Python编程中NotImplementedError的使用方法
Apr 21 #Python
python 通过字符串调用对象属性或方法的实例讲解
Apr 21 #Python
You might like
实现树状结构的两种方法
2006/10/09 PHP
php错误提示failed to open stream: HTTP request failed!的完美解决方法
2011/06/06 PHP
Zend Framework教程之分发器Zend_Controller_Dispatcher用法详解
2016/03/07 PHP
PHP生成制作验证码的简单实例
2016/06/12 PHP
Yii框架getter与setter方法功能与用法分析
2019/10/22 PHP
js获取当前select 元素值的代码
2010/04/19 Javascript
jquery(live)中File input的change方法只起一次作用的解决办法
2011/10/21 Javascript
JS判断元素为数字的奇异写法分享
2012/08/01 Javascript
jQuery实现的进度条效果
2015/07/15 Javascript
JS iFrame加载慢怎么解决
2016/05/13 Javascript
原生js调用json方法总结
2018/02/22 Javascript
详解Vue用cmd创建项目
2019/02/12 Javascript
实用Javascript调试技巧分享(小结)
2019/06/18 Javascript
ES6中Symbol、Set和Map用法详解
2019/08/20 Javascript
React Hooks 实现和由来以及解决的问题详解
2020/01/17 Javascript
python中Flask框架简单入门实例
2015/03/21 Python
python操作ie登陆土豆网的方法
2015/05/09 Python
Python 多核并行计算的示例代码
2017/11/07 Python
R语言 vs Python对比:数据分析哪家强?
2017/11/17 Python
Python中判断输入是否为数字的实现代码
2018/05/26 Python
python pandas.DataFrame选取、修改数据最好用.loc,.iloc,.ix实现
2018/06/11 Python
python利用ffmpeg进行录制屏幕的方法
2019/01/10 Python
Python多进程fork()函数详解
2019/02/22 Python
Django错误:TypeError at / 'bool' object is not callable解决
2019/08/16 Python
Python数据可视化:箱线图多种库画法
2019/11/06 Python
python实现Oracle查询分组的方法示例
2020/04/30 Python
Django如何使用redis作为缓存
2020/05/21 Python
Python实现加密接口测试方法步骤详解
2020/06/05 Python
细说CSS3中box属性中的overflow-x属性和overflow-y属性值的效果
2014/07/21 HTML / CSS
美国时尚假发购物网站:Wigsbuy
2019/04/06 全球购物
大专会计自我鉴定
2014/02/06 职场文书
《影子》教学反思
2014/02/21 职场文书
学习焦裕禄同志为人民服务思想汇报
2014/09/10 职场文书
单位工资证明范本
2015/06/12 职场文书
python编写函数注意事项总结
2021/03/29 Python
索尼ICF-36收音机评测
2022/04/30 无线电