Sembra che ci siano due motivi per cui una classe è "finale" in Python.
1. La violazione di invariante di classe
Le classi che seguono pattern Singleton hanno un invariante che c'è un numero limitato (predeterminato) di istanze. Qualsiasi violazione di questa invariante in una sottoclasse sarà incoerente con l'intento della classe e non funzionerebbe correttamente. Esempi:
bool
: True
, False
; vedi Guido's comments
NoneType
: None
NotImplementedType
: NotImplemented
ellipsis
: Ellipsis
Ci possono essere casi diversi dal pattern Singleton in questa categoria, ma io non sono a conoscenza di alcuna.
2. No Persuasive Use Case
Una classe implementato in C richiede un lavoro supplementare per consentire la creazione di sottoclassi (almeno in CPython). Fare questo lavoro senza un caso di utilizzo convincente non è molto allettante, quindi i volontari hanno meno probabilità di farsi avanti. Esempi:
Nota 1:
Ho inizialmente pensato che ci fossero casi d'uso valide, ma l'interesse semplicemente insufficiente, in sottoclassi di function
e operator.itemgetter
. Grazie a @agf per aver sottolineato che i casi d'uso offerti here e here non sono convincenti (vedi i commenti @agf alla domanda).
Nota 2:
mia preoccupazione è che un'altra implementazione di Python potrebbe accidentalmente consentire sottoclasse una classe che è in definitiva CPython. Ciò può causare codice non portatile (un caso d'uso può essere debole, ma qualcuno potrebbe scrivere codice che sottoclasse function
se il loro Python lo supporta). Questo può essere risolto contrassegnando nella documentazione di Python tutte le classi di libreria standard e incorporate che non possono essere sottoclasse e richiedendo che tutte le implementazioni seguano il comportamento di CPython a tale riguardo.
Nota 3:
Il messaggio prodotto da CPython in tutti i casi di cui sopra è:
TypeError: type 'bool' is not an acceptable base type
E 'abbastanza criptico, come numerose domande in questo show soggetto. Presenterò un suggerimento per aggiungere un paragrafo alla documentazione che spiega le classi finali e forse anche il messaggio di errore:
TypeError: type 'bool' is final (non-extensible)
'NoneType' è un altro esempio. – Duncan
Una classe finale in una implementazione Python può essere sottoclasmabile in un'altra implementazione? Spero che qualcuno possa confermare che non succede mai. Altrimenti, il codice scritto per un'implementazione potrebbe interrompersi quando trasferito su un'altra (anche molto dolorosamente: immagina se qualcuno ha sottoclasse 'function', e ora ha bisogno di rifattorizzare il codice per evitare questa ereditarietà). – max
Nota che PyPy si rifiuta di sottoclasse anche i tuoi quattro esempi ... anche se non ha la restrizione CPython. Potrebbero avere una ragione documentata nella loro base di codice. –