ホームページ  >  記事  >  バックエンド開発  >  Python デコレータに基づいてクラス内のメソッドを装飾する

Python デコレータに基づいてクラス内のメソッドを装飾する

不言
不言オリジナル
2018-04-21 14:50:532240ブラウズ

以下は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 メソッドがランダムに例外をスローし、プログラムがクラッシュする可能性があります。したがって、メソッド全体の処理を除いて、try...を実行する必要があります。最も醜いアプローチを次のコードに示します。

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()

このように書くと問題は解決できますが、コードは Python 的ではありません。

この問題を解決するにはデコレータを使用します。デコレータ関数はクラス内に記述するべきですか、それともクラス外に記述すべきですか?答えは、クラスの外で書くことです。では、クラスの外で書かれているので、このクラスの他のメソッドを呼び出すにはどうすればよいでしょうか?

まず、例外を処理するための最も一般的なデコレータを書きます:

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()の例外をキャプチャできますが、例外が発生した場合は別のメソッドを呼び出す必要があります。クラスで例外を処理するにはどうすればよいですか?答えは、ラッパーにパラメーターを追加することです: 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 デコレーター - 関数呼び出しの数を制限するメソッド (10 秒に 1 回呼び出し)

以上がPython デコレータに基づいてクラス内のメソッドを装飾するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。