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 装饰器装饰类中的方法的更多相关文章

  1. Python 学习 —— 进阶篇(装饰器、类的特殊方法)

    Python基础部分学完之后,在进入其OOP部分前,先理解一下其装饰器这种结构,其功能可类比于Java中的面向切面编程,下面参见具体实例: def log(f): def fn(x): print ' ...

  2. day20-Python运维开发基础(装饰器 / 类中的方法 / 类的方法变属性)

    1. 装饰器 / 类中的方法 / 类的方法变属性 # ### 装饰器 """ 定义:装饰器用于拓展原来函数功能的一种语法,返回新函数替换旧函数 优点:在不更改原函数代码的 ...

  3. 详解Python闭包,装饰器及类装饰器

    在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...

  4. Python 使用装饰器装饰类

    1.装饰器装饰函数 了解过或学过装饰器的同学都知道,Python 中的装饰器是可以装饰函数的,如: # 定义一个装饰器 def decorator(func): def inner(*args,**k ...

  5. python 装饰器 对类和函数的装饰

    #装饰器:对类或者函数进行功能的扩展  很多需要缩进的没有进行缩进'''#第一步:基本函数def laxi(): print('拉屎')#调用函数laxi()laxi() print('======= ...

  6. python 进阶篇 函数装饰器和类装饰器

    函数装饰器 简单装饰器 def my_decorator(func): def wrapper(): print('wrapper of decorator') func() return wrapp ...

  7. python 装饰器(七):装饰器实例(四)类装饰器装饰类以及类方法

    类装饰器装饰类方法 不带参数 from functools import wraps import types class CatchException: def __init__(self,orig ...

  8. python 装饰器(八):装饰器实例(五)函数装饰器装饰类以及类方法

    函数装饰器装饰类 单例模式 from functools import wraps def singleton(cls): instances = {} @wraps(cls) def get_ins ...

  9. Python中的多个装饰器装饰一个函数

    def wrapper1(func1): def inner1(): print('w1 ,before') func1() print('w1 after') return inner1 def w ...

随机推荐

  1. 2017-3-2 C# WindowsForm 中label标签居中显示

    有时候label标签要输出 label.text=""; 的语句,那么要把这个语句居中显示 1.要取消他的Autosize的值 2.拉大这个框,设置里面的文本的TextAlign ...

  2. 2017-02-23 switch case 循环语句

    另一个分支语句:switch..case.. switch(变量){    case 值:代码段;break;    case 值:代码段;break;    ...    default:代码段;b ...

  3. 深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!

    本文参考:http://www.dabeaz.com/coroutines/   作者:David Beazley 缘起: 本人最近在学习python的协程.偶然发现了David Beazley的co ...

  4. CoreAnimation 开篇

    CoreAnimation 开篇 CoreAnimation系列博客是我对学习CoreAnimation的知识整理,博客排列顺序以及知识讲解存在欠缺望见谅. 博客的编写是在工作之余,尽量保证CoreA ...

  5. 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课

    1644: [Usaco2007 Oct]Obstacle Course 障碍训练课 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 383  Solved ...

  6. JDBC-Eclipse & Mysql & Servlet实现

    import java.io.IOException;import java.io.PrintWriter;import java.sql.Connection;import java.sql.Dri ...

  7. How to set up Tensorflow inception-v3 model on Windows

    There is Inception-v3 model python implementation on GitHub at: https://github.com/tensorflow/models ...

  8. MySQL常用函数及日期

    一.数学函数 数学函数主要用于处理数字,包括整型.浮点数等. ABS(x) 返回x的绝对值 SELECT ABS(-1) -- 返回1 CEIL(x),CEILING(x) 返回大于或等于x的最小整数 ...

  9. paoding-rose 了解

    paoding-rose 是人人开源的基于 spring 开发的 javaEE 框架.wiki 地址: https://code.google.com/archive/p/paoding-rose/ ...

  10. Bootsrap 的 Carousel

    一.简介 Carousel 就是指轮播图,这里 有完整的代码例子.它可以很简单的就构造出来,结构如下: div.carousel.slide[data-ride="carousel" ...