1. ホーム
  2. python

[解決済み] サブクラス化できないクラスは?

2023-08-20 23:38:23

質問

組み込みクラスや標準ライブラリクラスでサブクラス化できないもの ("final") の決まりはありますか?

Python 3.3時点では、以下のような例があります。

  • bool
  • function
  • operator.itemgetter
  • slice

を発見しました。 質問 は、Cと純粋なPythonの両方で、"final" クラスの実装を扱っています。

私は、クラスがそもそも"final"であることが選択される理由を説明するかもしれないものを理解したいと思います。

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

Pythonでクラスが"final"である理由は2つあるようです。

1. クラス不変量の違反

Singletonパターンに従うクラスは、インスタンスの数が限られているという不変性を持っています(事前に決定されています)。サブクラスでこの不変量に違反すると、クラスの意図と矛盾し、正しく動作しなくなります。例を挙げます。

このカテゴリにはSingletonパターン以外のケースもありそうですが、私は把握していません。

2. 説得力のある使用事例がない

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

注1:

のサブクラス化には、有効なユースケースがあるが、単に関心が薄いだけだと考えていました。 functionoperator.itemgetter . を提供するユースケースであることを指摘してくれた @agf に感謝します。 ここで はこちら は説得力がありません(質問に対する@agfのコメントを参照してください)。

注2です。

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

注3:

上記の全てのケースでCPythonが生成するメッセージは、以下の通りです。

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

この件に関する多数の質問が示すように、これはかなり不可解です。ドキュメントに final class を説明する段落を追加する提案を提出し、エラーメッセージを変更するのもいいかもしれませんね。

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