Python 装饰器装饰类中的方法
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.
只需要修改装饰器定义的部分,使用装饰器的地方完全不需要做修改。
下图为正常运行时的运行结果:

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

通过添加一个self参数,类外面的装饰器就可以直接使用类里面的各种方法,也可以直接使用类的属性。
Python 装饰器装饰类中的方法的更多相关文章
- Python 学习 —— 进阶篇(装饰器、类的特殊方法)
Python基础部分学完之后,在进入其OOP部分前,先理解一下其装饰器这种结构,其功能可类比于Java中的面向切面编程,下面参见具体实例: def log(f): def fn(x): print ' ...
- day20-Python运维开发基础(装饰器 / 类中的方法 / 类的方法变属性)
1. 装饰器 / 类中的方法 / 类的方法变属性 # ### 装饰器 """ 定义:装饰器用于拓展原来函数功能的一种语法,返回新函数替换旧函数 优点:在不更改原函数代码的 ...
- 详解Python闭包,装饰器及类装饰器
在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...
- Python 使用装饰器装饰类
1.装饰器装饰函数 了解过或学过装饰器的同学都知道,Python 中的装饰器是可以装饰函数的,如: # 定义一个装饰器 def decorator(func): def inner(*args,**k ...
- python 装饰器 对类和函数的装饰
#装饰器:对类或者函数进行功能的扩展 很多需要缩进的没有进行缩进'''#第一步:基本函数def laxi(): print('拉屎')#调用函数laxi()laxi() print('======= ...
- python 进阶篇 函数装饰器和类装饰器
函数装饰器 简单装饰器 def my_decorator(func): def wrapper(): print('wrapper of decorator') func() return wrapp ...
- python 装饰器(七):装饰器实例(四)类装饰器装饰类以及类方法
类装饰器装饰类方法 不带参数 from functools import wraps import types class CatchException: def __init__(self,orig ...
- python 装饰器(八):装饰器实例(五)函数装饰器装饰类以及类方法
函数装饰器装饰类 单例模式 from functools import wraps def singleton(cls): instances = {} @wraps(cls) def get_ins ...
- Python中的多个装饰器装饰一个函数
def wrapper1(func1): def inner1(): print('w1 ,before') func1() print('w1 after') return inner1 def w ...
随机推荐
- 【翻译】LPeg编程指南
原文:http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html 译者序: 这个是官方的LPeg的文档.这段时间学习LPeg的时候发现国内关于LPeg的文章 ...
- JS判断手机当前的系统类型
<script language="javascript"> window.onload = function () { var n = navigator.userA ...
- 【js】性能问题
执行环境和作用域 一.全局变量和局部变量 每个执行环境都有与之关联的变量对象(变量和函数存储在这里),全局执行环境是最外围的执行环境,根据ECMA实现所在的宿主不同,表示的执行环境的对象也不同.在we ...
- 1625: [Usaco2007 Dec]宝石手镯
1625: [Usaco2007 Dec]宝石手镯 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 919 Solved: 618 [Submit][S ...
- JS实现购物车特效
学习通过JavaScript实现类似于淘宝的购物车效果,包括商品的单选.全选.删除.修改数量.价格计算.数目计算.预览等功能. 1. 实现兼容低版本IE的getElementsByClassName( ...
- js数据类型:引用和5种基本数据类型
javascript有2种基本数据类型:引用和基本数据类型 基本数据类型又有5个分类:布尔型.字符串.数值.undefined.NULL.
- SQL函数和SQL Server2008
1.绝对值 SQL:select abs(-1) value O:select abs(-1) value from dual 2.取整(大) S:select ceiling(-1.00 ...
- 连接池 DBCP c3p0以及分页的案例
1. 连接池 思考: 程序中连接如何管理? 连接资源宝贵:需要对连接管理 连接: a) 操作数据库,创建连接 b) 操作结束, 关闭! 分析: 涉及频繁的连接的打开.关闭,影响程序的运行效率! 连接 ...
- ubuntu下命令使用
sudo apt-get -f install:修复函数依赖 df -hl:查看空间使用状况 nvidia-smi:常看GPU使用率
- Seajs使用实例入门介绍
本文所用例子的代码目录结构: seajs example |--sea-module //存在依赖文件 |--jquery |--jqeury.js |--sea.js |--static //存放自 ...