基於Python 裝飾器裝飾類別中的方法

不言
發布: 2018-04-21 14:50:53
原創
2243 人瀏覽過

以下為大家分享一篇基於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裝飾器-限制函數呼叫次數的方法(10s呼叫一次)

以上是基於Python 裝飾器裝飾類別中的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板