Python 装饰器装饰类中的方法
时间:2022-06-17
本文章向大家介绍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 wrapperclass 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 wrapperclass 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参数,类外面的装饰器就可以直接使用类里面的各种方法,也可以直接使用类的属性。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 面试官:mysql如何重置自增id
- 如何在kubernete集群上部署springboot应用
- lettuce连接池很香,撸撸它的源代码
- 浅谈kubernete中的flannel网络插件
- 聊聊Java中CompletableFuture的使用
- 开发更高可用、高质量的服务的一些建议
- kubernete编排技术一:pod
- Golang逃逸分析
- kubernete编排技术二:deployment
- Gearman介绍、原理分析、实践改进
- 『JWT』,你必须了解的认证登录方案
- 静态网站
- ansible超详细使用指南
- Linux下快速安装Python3和pip
- 面试官:谈一谈java中基于AQS的并发锁原理