1. ホーム
  2. パイソン

[解決済み】Pythonで抽象基底クラスを使用する理由は?

2022-04-02 13:50:56

質問

私はPythonの古いダックタイピングの方法に慣れているので、ABC(抽象ベースクラス)の必要性を理解できません。その ヘルプ は、その使い方がよくわかります。

の根拠を読もうとしたのですが PEP しかし、それは私の頭の上を通り過ぎた。もし私がミュータブルシーケンスコンテナを探しているのであれば、以下のものをチェックすることになるでしょう。 __setitem__ を使うか、あるいはそれを使おうとする可能性が高い( EAFP ). を実際に使う場面には遭遇していません。 数字 モジュールは、ABCを使用していますが、これが私の理解に最も近いものです。

どなたかその根拠を説明していただけませんか?

どのように解決するのですか?

ショートバージョン

ABCは、クライアントと実装されたクラスとの間に、より高度な意味的契約を提供する。

ロングバージョン

クラスとその呼び出し元との間には契約があります。クラスは、あることを行い、ある特性を持つことを約束します。

契約にはさまざまなレベルがあります。

非常に低いレベルでは、契約にはメソッドの名前やパラメータの数が含まれるかもしれません。

静的型付け言語では、この契約は実際にはコンパイラによって強制されます。Pythonでは EAFP または型イントロスペクションによって、未知のオブジェクトがこの期待される契約を満たしていることを確認します。

しかし、契約にはより高度な、意味上の約束もある。

例えば __str__() メソッドは、オブジェクトの文字列表現を返すことが期待されています。それは かもしれない オブジェクトのすべてのコンテンツを削除し、トランザクションをコミットし、プリンタから白紙のページを吐き出す...しかし、それが何をすべきかという共通の理解があり、Pythonのマニュアルに記載されています。

それは特殊なケースで、意味上の契約はマニュアルに記述されています。 この場合 print() メソッドは何をするのでしょうか?オブジェクトをプリンタに書き出すべきなのか、画面に一行書き出すべきなのか、それとも別の何かなのか?それは場合による - ここでの完全な契約を理解するには、コメントを読む必要があります。クライアントコードの一部で、単に print() メソッドが存在することを確認したのであって、そのメソッド呼び出しが可能であることを確認したのであって、その呼び出しの上位レベルのセマンティクスについて合意したわけではありません。

Abstract Base Class (ABC) を定義することは、クラスの実装者と呼び出し側との間の契約を作り出す方法です。これは、単なるメソッド名のリストではなく、それらのメソッドが何を行うべきかという理解を共有するものです。この ABC を継承した場合、コメントで説明されているすべてのルール、つまり、メソッドのセマンティクスを含む print() メソッドを使用します。

Pythonのダックタイピングは、静的型付けに比べて柔軟性で多くの利点がありますが、すべての問題を解決できるわけではありません。ABCはPythonの自由形式と静的型付け言語の束縛と規律の間の中間的な解決策を提供します。