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 装饰器装饰类中的方法实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持小牛知识库。
问题内容: 考虑这个小例子: 哪个打印 为什么参数(应该是Test obj实例)没有作为第一个参数传递给装饰函数? 如果我手动进行操作,例如: 它按预期工作。但是,如果我必须事先知道某个函数是否装饰,它就破坏了装饰器的全部目的。这里的模式是什么,还是我误会了什么? 问题答案: tl; dr 您可以通过将类作为描述符并返回部分应用的函数来解决此问题,该函数从中应用对象作为参数之一,如下所示 实际问题
问题内容: 我已经看到许多Python装饰器的示例,它们是: 函数样式修饰符(包装函数) 类风格装饰(实施,和) 不带参数的装饰器 带参数的装饰器 “方法友好”的装饰器(即可以装饰类中的方法) “功能友好”的装饰器(可以装饰普通功能 可以装饰方法和功能的装饰器 但是我从未见过一个可以完成上述所有操作的示例,而且我无法从各种答案到特定问题,这个或这个上看到过,如何结合以上所有内容。 我想要的是一个
问题内容: 我想构造用作装饰器的类,并保留以下原则: 应该有可能在top 1函数上堆叠多个此类装饰器。 产生的函数名称指针应该与没有装饰器的相同函数没有区别,可能只是它是哪种类型/类。 除非装饰员实际要求,否则订购装饰员应该无关紧要。就是 独立的装饰器可以以任何顺序应用。 这是针对Django项目的,现在我正在处理的特定情况下,该方法需要2个装饰器,并显示为普通的python函数: @AutoTe
本文向大家介绍Python类装饰器实现方法详解,包括了Python类装饰器实现方法详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python类装饰器。分享给大家供大家参考,具体如下: 编写类装饰器 类装饰器类似于函数装饰器的概念,但它应用于类,它们可以用于管理类自身,或者用来拦截实例创建调用以管理实例。 单体类 由于类装饰器可以拦截实例创建调用,所以它们可以用来管理一个类的所有实例,
问题内容: 有没有办法像python风格那样装饰C ++中的函数或方法? 例如,使用宏: 要么 可能吗? 问题答案: 提供了我提出的解决方案的大多数构建块。 这是我建议的解决方案。 输出: ps 提供了一个可以进行功能调用以外的其他功能的地方。如果您想简单地传递至,可以使用:
问题内容: 我正在尝试学习装饰器。我了解它的概念,现在尝试实现它。 这是我编写 的代码,代码不言自明。它只是检查参数是否传入。 抛出错误的说法。我了解它未在下定义,但不知道如何纠正此代码?我要去哪里错了? 问题答案: 您的装饰器应如下所示: 需要注意的几点: 期望将类作为第一个参数(您可以将其替换为简单的try / except TypeError除外)。 包装器应返回一个函数,而不是被调用函数的