基于Python 装饰器装饰类中的方法实例
作者:hesi9555 发布时间:2023-10-11 04:10:22
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参数,类外面的装饰器就可以直接使用类里面的各种方法,也可以直接使用类的属性。
来源:https://blog.csdn.net/hesi9555/article/details/70224911
猜你喜欢
- 本文实例为大家分享了python实现五子棋游戏的具体代码,供大家参考,具体内容如下先上代码 #调用pygame库import py
- row_number()over(partition by col1 order by col2)表示根据col1分组,在分组内部根据col
- 如下所示:安装kafka支持库pip install kafka-pythonfrom kafka import KafkaProducer
- 本文实例为大家分享了python实现抠图给证件照换背景的具体代码,供大家参考,具体内容如下import cv2import numpy as
- 对于大多数数据科学家而言,线性回归方法是他们进行统计学建模和预测分析任务的起点。这种方法已经存在了 200 多年,并得到了广泛研究,但仍然是
- 如何正确理解和使用Command、Connection和 Recordset三个对象?我知道它们都是连接数据库的“好手”,但在编程的具体应用
- mysql找不到my.ini文件问题描述刚刚在修改mysql默认配置的时候,发现找不到my.ini文件。按照其他搬运工的说法,打开隐藏的文件
- Mysql自增主键id不是以此逐级递增一、介绍在mysql数据库添加数据时使用ON DUPLICATE KEY UPDATE进行数据更新时可
- 本文介绍了webpack对样式的处理,分享给大家,具体如下:我们可以在js中引入样式文件require('myStyle.css
- 这是 2020 年第 3 个版本,也是最后一个版本。在 GoLand 2020.3 中,您可以探索 goroutines dumps,运行并
- 本文实例讲述了Python保存最后N个元素的方法。分享给大家供大家参考,具体如下:问题:希望在迭代或是其他形式的处理过程中对最后几项记录做一
- 在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScrip
- 研究(2)中讨论了栅格系统的基础知识。这一篇将集中探讨栅格系统的粒度问题。(注:如非特别指明,栅格系统均指24列960栅格系统)淘宝的首页(
- MSSQL2005数据库版本 SQL Server 2005 的各版本之间选择 大多数企业都在三个 SQL Ser
- 需要先安装openpyxl库通过pip命令安装: pip install openpyxl源码如下:#!/usr/bin/python3#-
- 一、ready函数的实现经常用jQuery类库或其他类库中的ready方法,有时候想想它们到底是怎么实现的,但是看了一下jQuery中的源码
- //CLASS@Mr.Think*****getElementsByTagName function tag(name,elem){ if(
- <!doctype html> <html> <head> <meta charset="
- 写这个文章绝对是偶然的偶然的机会,前年等一回的 元旦节,和 老婆上街 溜达,猛然想起买上一张福利彩票,结果屁都没有中上,开春第一
- 过年前产假归来,jmeter很多知识生疏了,这两天打开jmeter摸索了几下,老了记不住,还是准备弄个jmeter系列随笔吧。言归正传,使用