基于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的randrange()方法使用教程
May 15 Python
教你用Type Hint提高Python程序开发效率
Aug 08 Python
详解Django rest_framework实现RESTful API
May 24 Python
python2 与 python3 实现共存的方法
Jul 12 Python
pytorch中tensor的合并与截取方法
Jul 26 Python
Linux下python3.6.1环境配置教程
Sep 26 Python
使用python Fabric动态修改远程机器hosts的方法
Oct 26 Python
pycharm 中mark directory as exclude的用法详解
Feb 14 Python
浅谈tensorflow模型保存为pb的各种姿势
May 25 Python
pytorch  网络参数 weight bias 初始化详解
Jun 24 Python
最简单的matplotlib安装教程(小白)
Jul 28 Python
pytorch 中autograd.grad()函数的用法说明
May 12 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+mysqli实现批量执行插入、更新及删除数据的方法
2015/01/29 PHP
PHP开发注意事项总结
2015/02/04 PHP
PHP支付宝当面付2.0代码
2018/12/21 PHP
PHP+redis实现微博的拉模型案例详解
2019/07/10 PHP
二级域名或跨域共享Cookies的实现方法
2008/08/07 Javascript
kmock javascript 单元测试代码
2011/02/06 Javascript
jQuery 源码分析笔记(4) Ready函数
2011/06/02 Javascript
根据经纬度计算地球上两点之间的距离js实现代码
2013/03/05 Javascript
php与js的区别是什么
2013/08/05 Javascript
将input file的选择的文件清空的两种解决方案
2013/10/21 Javascript
js+html5通过canvas指定开始和结束点绘制线条的方法
2015/06/05 Javascript
基于css3新属性transform及原生js实现鼠标拖动3d立方体旋转
2016/06/12 Javascript
jquery实现文本框的禁用和启用
2016/12/07 Javascript
JS实现线性表的链式表示方法示例【经典数据结构】
2017/04/11 Javascript
JavaScript实现省市县三级级联特效
2017/05/16 Javascript
jQuery实现 RadioButton做必选校验功能
2017/06/15 jQuery
Vue Router 实现动态路由和常见问题及解决方法
2020/03/06 Javascript
[03:24]CDEC.Y赛前采访 努力备战2016国际邀请赛中国区预选赛
2016/06/25 DOTA
Python使用微信SDK实现的微信支付功能示例
2017/06/30 Python
Python编程把二叉树打印成多行代码
2018/01/04 Python
使用python脚本实现查询火车票工具
2018/07/19 Python
Python判断是否json是否包含一个key的方法
2018/12/31 Python
pandas统计重复值次数的方法实现
2021/02/20 Python
英国工具中心:UK Tool Centre
2017/07/10 全球购物
欧洲领先的技术商店:eibmarkt.com
2019/05/10 全球购物
大学生入党自我鉴定
2013/10/31 职场文书
资料员的岗位职责
2013/11/20 职场文书
应届毕业生通用的自荐书范文
2014/02/07 职场文书
安卓程序员求职信
2014/02/28 职场文书
初中生评语大全
2014/04/24 职场文书
团党委领导干部党的群众路线教育实践活动个人对照检查材料思想汇
2014/10/05 职场文书
见习报告格式要求
2014/11/04 职场文书
Django分页器的用法你都了解吗
2021/05/26 Python
在redisCluster中模糊获取key方式
2021/07/09 Redis
用JS写一个发布订阅模式
2021/11/07 Javascript
pytest实现多进程与多线程运行超好用的插件
2022/07/15 Python