Es scheint zwei Gründe dafür zu geben, dass eine Klasse in Python "endgültig" ist.
1. Verletzung der Klasseninvariante
Klassen, die dem Singleton-Muster folgen, haben die Invariante, dass es eine begrenzte (vorher festgelegte) Anzahl von Instanzen gibt. Jeder Verstoß gegen diese Invariante in einer Unterklasse widerspricht der Absicht der Klasse und würde nicht richtig funktionieren. Beispiele:
bool
: True
, False
; siehe Guidos Kommentare
NoneType
:: None
NotImplementedType
:: NotImplemented
ellipsis
:: Ellipsis
Es kann andere Fälle als das Singleton-Muster in dieser Kategorie geben, aber mir sind keine bekannt.
2. Kein überzeugender Anwendungsfall
Eine in C implementierte Klasse erfordert zusätzliche Arbeit, um Unterklassen zu ermöglichen (zumindest in CPython). Solche Arbeiten ohne einen überzeugenden Anwendungsfall durchzuführen, ist nicht sehr attraktiv, daher ist es weniger wahrscheinlich, dass Freiwillige sich melden. Beispiele:
Anmerkung 1:
Ich dachte ursprünglich, es gäbe gültige Anwendungsfälle, aber einfach unzureichendes Interesse an der Unterklasse von function
und operator.itemgetter
. Vielen Dank an @agf für den Hinweis, dass die hier und hier angebotenen Anwendungsfälle nicht überzeugend sind (siehe @agf-Kommentare zur Frage).
Anmerkung 2:
Ich befürchte, dass eine andere Python-Implementierung versehentlich die Unterklasse einer Klasse zulässt, die in CPython endgültig ist. Dies kann zu nicht portierbarem Code führen (ein Anwendungsfall kann schwach sein, aber jemand schreibt möglicherweise immer noch Code, der in Unterklassen unterteilt ist, function
wenn sein Python dies unterstützt). Dies kann behoben werden, indem in der Python-Dokumentation alle integrierten und Standardbibliotheksklassen markiert werden, die nicht in Unterklassen unterteilt werden können, und dass alle Implementierungen in dieser Hinsicht dem CPython-Verhalten folgen müssen.
Notiz 3:
Die von CPython in allen oben genannten Fällen erzeugte Nachricht lautet:
TypeError: type 'bool' is not an acceptable base type
Es ist ziemlich kryptisch, wie zahlreiche Fragen zu diesem Thema zeigen. Ich werde einen Vorschlag einreichen, um der Dokumentation einen Absatz hinzuzufügen, in dem die letzten Klassen erläutert werden, und möglicherweise sogar die Fehlermeldung in Folgendes ändern:
TypeError: type 'bool' is final (non-extensible)
NoneType
ist ein weiteres Beispiel.