web-dev-qa-db-ja.com

サブクラス化できないクラスはどれですか?

どの組み込みおよび標準ライブラリクラスがサブクラス化できない(「最終」)かについての規則はありますか?

Python 3.3以降、いくつかの例を示します。

  • bool
  • function
  • operator.itemgetter
  • slice

Cと純粋なPythonの両方で「最終」クラスの実装を扱う question を見つけました。

そもそもクラスが「ファイナル」に選ばれた理由を説明したいのですが。

72
max

Pythonでクラスが「最終」になる理由は2つあるようです。

1。クラス不変式の違反

シングルトンパターンに従うクラスには、インスタンスの数が(事前に)制限されているという不変条件があります。サブクラスでこの不変条件に違反すると、クラスの意図と矛盾し、正しく機能しなくなります。例:

  • boolTrueFalse; Guidoのコメント を参照してください
  • NoneTypeNone
  • NotImplementedTypeNotImplemented
  • EllipsisEllipsis

このカテゴリにはシングルトンパターン以外のケースもあるかもしれませんが、私は知りません。

2。説得力のあるユースケースなし

Cで実装されたクラスは、サブクラス化を可能にするために追加の作業を必要とします(少なくともCPythonでは)。説得力のあるユースケースなしでそのような作業を行うことはあまり魅力的ではないため、ボランティアが前に出る可能性は低くなります。例:

注1:

私は当初、functionoperator.itemgetterのサブクラス化には、有効なユースケースがあると思っていましたが、関心が不十分でした。提供されたユースケース ここ および ここ が説得力がないことを指摘してくれた@agfに感謝します(質問に対する@agfのコメントを参照)。

注2:

私の懸念は、別のPython実装が、CPythonで最終的なクラスのサブクラス化を誤って許可する可能性があることです。これにより、移植性のないコードが生成される可能性があります(ユースケースは弱いかもしれませんが、誰かがそれでもコードを書く可能性があります)サブクラスfunction if their Python support it)。これは、Pythonドキュメントで、すべての組み込みおよび標準ライブラリクラスをマークすることで解決できます。サブクラス化することはできず、すべての実装がその点でCPythonの動作に従う必要があります。

注3:

上記のすべての場合にCPythonによって生成されるメッセージは次のとおりです。

TypeError: type 'bool' is not an acceptable base type

この主題に関する多くの質問が示すように、それはかなり不可解です。最終クラスを説明する段落をドキュメントに追加する提案を送信し、エラーメッセージを次のように変更することもできます。

TypeError: type 'bool' is final (non-extensible)
26
max