python 类方法装饰器_Python 装饰器装饰类中的方法

本文介绍了如何使用Python装饰器来优雅地处理类方法中的异常。通过创建一个外部装饰器,并在装饰器中添加`self`参数,使得装饰器能够访问和调用类的其他方法。以捕获并处理`read_value`方法可能抛出的异常为例,展示了装饰器如何增强代码的可读性和Pythonic风格。通过这种方法,可以在不修改原有类方法代码的情况下,实现异常的捕获和自定义处理。
摘要由CSDN通过智能技术生成

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.

只需要修改装饰器定义的部分,使用装饰器的地方完全不需要做修改。

下图为正常运行时的运行结果:

L3Byb3h5L2h0dHAvN3NicG1wLmNvbTEuejAuZ2xiLmNsb3VkZG4uY29tLzIwMTctMDQtMTctMjEtMTktMjUucG5n.jpg

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

L3Byb3h5L2h0dHAvN3NicG1wLmNvbTEuejAuZ2xiLmNsb3VkZG4uY29tLzIwMTctMDQtMTctMjEtMjAtNTkucG5n.jpg

通过添加一个self参数,类外面的装饰器就可以直接使用类里面的各种方法,也可以直接使用类的属性。

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 ...

随机推荐

SQL Server 2008 R2 安装出错:Could not open key

安装Sql Server 2008 R2 企业版出现错误提示无法继续安装,错误提示为: Could not open key: UNKNOWN\Components\7ABFE44842C12B390 ...

新浪微博授权时出现"关注 *** 的微博"

基本设置完成后, 保证scope是 "all" 或 至少 包含 "follow_app_official_microblog". 测试时, 保证你的测试账号没有 ...

PAT - IO-01. 表格输出(5)

题目: 本题要求编写程序,按照规定格式输出表格. 输入格式: 本题目没有输入. 输出格式: 要求严格按照给出的格式输出下列表格: ----------------------------------- ...

awk取每行最大值

需求 有一个数字文本,每行都是数字,以空格分开:现在需要将每行中最大值取出来 文本如下: [root@localhost ~]#cat urfile 1 1 2 1 2 1 1 3 1 使用awk解决 ...

Java 8 异常该进

try-with-resources 这个特性是在JDK7中出现的,我们在之前操作一个流对象的时候大概是这样的: try { // 使用流对象 stream.read(); stream.write( ...

NGINX安全

http://anyun.org/a/jishuguanzhu/WEBjishu/2017/0804/8721.html

交互软件Axure—高保真原型

在上一篇文章中跟大家分享了Axure7.0 的简介.基本操作和原型图的制作,主要是应用元件库里的原件进行界面元素的搭建,直至完成原型图,在最后给大家展示了高保真原型图效果.而在本次分享中,主要带领大家 ...

HTML5-入门2。

文本样式 加粗 倾斜 下划线 删除线 < ...

centos系统下禁用笔记本触控板

最近把零几年的老爷笔记本拿出来用,使用windows系统实在太卡了,于是折腾安装上Centos系统了,但是在使用的过程中发现鼠标经常失效.使用了多种方法(比如:http://blog.csdn.net ...

css如何将div画成三角形

首先了解一下盒模型: 盒模型 先看一段代码: #div1{ height: 100px; border-style: solid; border-width: 100px 100px 100px 10 ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值