基于Python 裝飾器裝飾類中的方法實(shí)例
title: Python 裝飾器裝飾類中的方法
comments: true
date: 2017-04-17 20:44:31
tags: ['Python', 'Decorate']
category: ['Python']
---
目前在中文網(wǎng)上能搜索到的絕大部分關(guān)于裝飾器的教程,都在講如何裝飾一個(gè)普通的函數(shù)。本文介紹如何使用Python的裝飾器裝飾一個(gè)類的方法,同時(shí)在裝飾器函數(shù)中調(diào)用類里面的其他方法。本文以捕獲一個(gè)方法的異常為例來進(jìn)行說明。
有一個(gè)類Test, 它的結(jié)構(gòu)如下:
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.
在類中有一個(gè)方法read_value(),這個(gè)方法在多個(gè)地方被調(diào)用。由于某些原因,方法read_value有可能隨機(jī)拋出Exception導(dǎo)致程序崩潰。所以需要對(duì)整個(gè)方法做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。
使用裝飾器來解決這個(gè)問題,裝飾器函數(shù)應(yīng)該寫在類里面還是類外面呢?答案是,寫在類外面。那么既然寫在類外面,如何調(diào)用這個(gè)類的其他方法呢?
首先寫出一個(gè)最常見的處理異常的裝飾器:
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.
這種寫法,確實(shí)可以捕獲到origin_func()的異常,但是如果在發(fā)生異常的時(shí)候,需要調(diào)用類里面的另一個(gè)方法來處理異常,這又應(yīng)該怎么辦?答案是給wrapper增加一個(gè)參數(shù):self.
代碼變?yōu)槿缦滦问剑?/strong>
def catch_exception(origin_func):
def wrapper(self, *args, **kwargs):
try:
u = origin_func(self, *args, **kwargs)
return u
except Exception:
self.revive() #不用顧慮,直接調(diào)用原來的類的方法
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.
只需要修改裝飾器定義的部分,使用裝飾器的地方完全不需要做修改。
下圖為正常運(yùn)行時(shí)的運(yùn)行結(jié)果:

下圖為發(fā)生異常以后捕獲并處理異常:

通過添加一個(gè)self參數(shù),類外面的裝飾器就可以直接使用類里面的各種方法,也可以直接使用類的屬性。
以上這篇基于Python 裝飾器裝飾類中的方法實(shí)例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python連接MySQL數(shù)據(jù)庫實(shí)例分析
這篇文章主要介紹了python連接MySQL數(shù)據(jù)庫,實(shí)例分析了Python操作MySQL的相關(guān)技巧,需要的朋友可以參考下2015-05-05
pycharm導(dǎo)入第三方庫的兩種方法(永不報(bào)錯(cuò))
這篇文章主要介紹了pycharm導(dǎo)入第三方庫的兩種方法(永不報(bào)錯(cuò)),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11

