基於Python 裝飾器裝飾類中的方法例項

基於Python 裝飾器裝飾類中的方法例項

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 裝飾器裝飾類中的方法例項就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援指令碼之家。

您可能感興趣的文章:

Python裝飾器用法例項總結Python裝飾器原理與用法分析Python裝飾器原理與簡單用法例項分析使用python裝飾器計算函式執行時間的例項python裝飾器-限制函式呼叫次數的方法(10s呼叫一次)Python 3.7新功能之dataclass裝飾器詳解python裝飾器深入學習python如何修改裝飾器中引數python如何定義帶引數的裝飾器Python裝飾器知識點補充