Fumiのブログ

ABCMetaクラスについて | Python備忘録

#はじめに

時々コードの中でABCMetaクラスを継承してゴニョゴニョしているコードがあって、なんかやってるんだなぁっていうくらいでスルーしていたけど、今度開く勉強会のためにLINEボットのSDKで使っているから、まぁ一応調べるかぁってことで検索した備忘録。

ちなみに、勉強会はこちら↓

#読んだもの

#結論

公式ドキュメントで抽象基底クラスって結局なんだ...ってなってたけど、他の2つの記事を読んで、 JavaのInterfaceみたいなことが出来て継承することで抽象化クラスになるらしいことがわかった。 自分はJavaはあまり使わないからInterfaceについては慣れ親しんではないけど、 以前「Java言語で学ぶデザインパターン入門」を読みながらC++のコードで書き直しているときに、 Interfaceってなんだって調べてたからすんなりと受け入れられた気がする( ・∀・)

ちなみに、Pythonでなんで抽象基底クラスが必要かという理由はPEP3119に載っています。 理由の箇所をGoogle翻訳先生によって、日本語にしたものが次です。

オブジェクト指向プログラミングの分野では、オブジェクトと対話するための使用パターンは、「呼び出し」と「検査」の2つの基本的なカテゴリに分けられます。 呼び出しとは、そのメソッドを呼び出すことによってオブジェクトと対話することを意味します。通常、これはポリモーフィズムと組み合わされているため、メソッドを呼び出すとオブジェクトのタイプによって異なるコードが実行される可能性があります。 検査とは、オブジェクトのメソッドの外部にある外部コードがそのオブジェクトのタイプまたはプロパティを調べ、その情報に基づいてそのオブジェクトをどのように扱うかを決定する能力を意味します。 どちらの使用パターンも、多様で潜在的に新規なオブジェクトの処理を統一的にサポートすることができる同じ一般的な目的を果たしますが、同時に、異なる種類のオブジェクトごとに処理の決定をカスタマイズすることができます。 古典的なOOP理論では、呼び出しが望ましい使用パターンであり、検査は積極的に推奨されず、初期の手続き型プログラミングスタイルの遺物とみなされています。しかし実際には、この見方はあまりにも独断的で柔軟性がなく、Pythonのような言語の動的な性質とは非常に似通った設計剛性につながります。 特に、オブジェクトクラスの作成者が予期しない方法でオブジェクトを処理する必要がしばしばあります。そのオブジェクトのすべての可能なユーザーのニーズを満たすすべてのオブジェクトメソッドを構築するのは、常に最適なソリューションではありません。さらに、オブジェクト内に厳密にカプセル化されている従来のOOPの動作要件とは対照的に、ルールやパターンマッチドリブンロジックなどの強力なディスパッチ哲学が多数存在します。 他方、古典的なOOP理論家による検査の批判の1つは、フォーマリズムの欠如と検査対象の臨機応変な性質である。 Pythonのように、オブジェクトのほとんどすべての側面が反映され、外部コードに直接アクセスできる言語では、オブジェクトが特定のプロトコルに準拠しているかどうかをテストするさまざまな方法があります。たとえば、 'このオブジェクトは変更可能なシーケンスコンテナですか?'と尋ねると、 'list'の基本クラスを探すか、 '__getitem__'という名前のメソッドを探すことができます。しかし、これらのテストは明白に見えるかもしれませんが、どちらも正しいとは言えません。 一般的に合意された救済策は、テストを標準化し、正式な手配にグループ分けすることです。これは、継承メカニズムまたはその他の手段を使用して、各クラスに標準のテスト可能なプロパティのセットを関連付けることで最も簡単に実行できます。各テストには、クラスの一般的な振る舞いについての約束と、他のクラスメソッドが利用可能になることについての約束が含まれています。 このPEPでは、抽象基本クラス(ABC)と呼ばれるこれらのテストを構成するための特別な戦略を提案しています。 ABCはPythonクラスで、オブジェクトの継承ツリーに追加され、そのオブジェクトの特定の機能を外部のインスペクタに通知します。テストはisinstance()を使用して行われ、特定のABCの存在はテストが合格したことを意味します。 さらに、ABCは、型の特徴的な振る舞いを確立する最小限のメソッドのセットを定義します。 ABC型に基づいてオブジェクトを識別するコードは、それらのメソッドが常に存在すると信じることができます。これらのメソッドのそれぞれには、ABCのドキュメントに記述されている一般化された抽象セマンティック定義が付いています。これらの標準的な意味定義は強制されませんが、強く推奨されます。 Pythonの他のすべてのものと同様に、これらの約束は紳士協定の本質的なものであり、この場合、ABCで約束された約束を実行するが、具体的なクラスの実施者残りのものは保管されています。

ということで、適切にこの子を使うとちゃんとクラス設計した時にいい感じに働いてくれて良さげ。 これからは使うようにしよう。