基于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实现给文件添加内容及得到文件信息的方法
May 28 Python
Python中set与frozenset方法和区别详解
May 23 Python
浅谈pyhton学习中出现的各种问题(新手必看)
May 17 Python
机器学习python实战之手写数字识别
Nov 01 Python
python 获取一个值在某个区间的指定倍数的值方法
Nov 12 Python
python实现可变变量名方法详解
Jul 01 Python
python删除列表元素的三种方法(remove,pop,del)
Jul 22 Python
python对常见数据类型的遍历解析
Aug 27 Python
TensorFlow实现保存训练模型为pd文件并恢复
Feb 06 Python
使用已经得到的keras模型识别自己手写的数字方式
Jun 29 Python
python gui开发——制作抖音无水印视频下载工具(附源码)
Feb 07 Python
教你使用Python获取QQ音乐某个歌手的歌单
Apr 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
php中通过smtp发邮件的类,测试通过
2007/01/22 PHP
PHP调用VC编写的COM组件实例
2014/03/29 PHP
php之curl实现http与https请求的方法
2014/10/21 PHP
javascript 判断字符串是否包含某字符串及indexOf使用示例
2013/10/18 Javascript
jQuery中next()方法用法实例
2015/01/07 Javascript
JavaScript使用二分查找算法在数组中查找数据的方法
2015/04/07 Javascript
基于jQuery实现左侧菜单栏可折叠功能
2016/12/27 Javascript
JavaScript定义函数_动力节点Java学院整理
2017/06/27 Javascript
老生常谈ES6中的类
2017/07/31 Javascript
详解设置Webstorm 利用babel将ES6自动转码成ES5
2017/12/20 Javascript
Vue.js 2.0和Cordova开发webApp环境搭建方法
2018/02/26 Javascript
[55:04]海涛DOTA2死魂复燃6.82版本介绍
2014/09/28 DOTA
Python ORM框架SQLAlchemy学习笔记之关系映射实例
2014/06/10 Python
python实现超简单端口转发的方法
2015/03/13 Python
Python使用django获取用户IP地址的方法
2015/05/11 Python
Python的Django框架可适配的各种数据库介绍
2015/07/15 Python
Python编程中对文件和存储器的读写示例
2016/01/25 Python
Python实现简单的语音识别系统
2017/12/13 Python
分享一下Python数据分析常用的8款工具
2018/04/29 Python
python用fsolve、leastsq对非线性方程组求解
2018/12/15 Python
Python3中编码与解码之Unicode与bytes的讲解
2019/02/28 Python
关于Python中的向量相加和numpy中的向量相加效率对比
2019/08/26 Python
Django自带日志 settings.py文件配置方法
2019/08/30 Python
PYQT5开启多个线程和窗口,多线程与多窗口的交互实例
2019/12/13 Python
Python3打包exe代码2种方法实例解析
2020/02/17 Python
Python函数参数分类原理详解
2020/05/28 Python
Python爬取网站图片并保存的实现示例
2021/02/26 Python
使用CSS3的box-sizing属性解决div宽高被内边距撑开的问题
2016/06/28 HTML / CSS
HTML5 input元素类型:email及url介绍
2013/08/13 HTML / CSS
Hotels.com加拿大:领先的在线住宿网站
2018/10/05 全球购物
领导证婚人证婚词
2014/01/13 职场文书
网络技术专业求职信
2014/05/02 职场文书
乡镇党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
字典算法实现及操作 --python(实用)
2021/03/31 Python
Nginx配置SSL证书出错解决方案
2021/03/31 Servers
如何通过cmd 连接阿里云服务器
2022/04/18 Servers