È convenzionale generare un NotImplementedError per i metodi la cui implementazione è in sospeso, ma non si prevede che siano astratti?


34

Mi piace raccogliere un NotImplementedErrorper qualsiasi metodo che voglio implementare, ma dove non sono ancora riuscito a farlo. Potrei già avere un'implementazione parziale, ma anteponilo raise NotImplementedError()perché non mi piace ancora. D'altra parte, mi piace anche attenermi alle convenzioni, perché ciò faciliterà il mantenimento del mio codice da parte di altre persone e le convenzioni potrebbero esistere per una buona ragione.

Tuttavia la documentazione di Pythons per NotImplementedError afferma:

Questa eccezione è derivata da RuntimeError. Nelle classi di base definite dall'utente, i metodi astratti dovrebbero sollevare questa eccezione quando richiedono che le classi derivate abbiano la precedenza sul metodo.

Questo è un caso d'uso molto più specifico e formale di quello che descrivo. È uno stile buono e convenzionale sollevare NotImplementedErrorsemplicemente per indicare che questa parte dell'API è un work in progress? In caso contrario, esiste un modo standardizzato diverso per indicarlo?


Cosa intendi con "appropriato?"
Robert Harvey,

1
@RobertHarvey Suppongo che intendo convenzionale, seguendo un uso comune. Ho riformulato la mia domanda ora.
Gerrit,

1
Usiamo C # qui principalmente, ma quel tipo di lancio di eccezioni è idiomatico qui, e mi aspetterei altrove. Rompere presto e rompere rumorosamente è una buona linea guida per identificare rapidamente potenziali problemi (leggi: a buon mercato).
Telastyn,

In genere, se sto creando una classe, inserisco i commenti TODO in metodi non implementati fino a quando non riesco a implementare la funzionalità. Se la classe fosse stata messa in produzione prima che ciò accadesse, prenderei in considerazione il lancio di eccezioni.

5
Per quello che vale, questo è ciò che fa Microsoft Visual Studio per impostazione predefinita quando si utilizza l'IDE per "implementare un'interfaccia". Secondo Robert Harvey, il risultato è ben compreso.
Cibo per gatti

Risposte:


34

Vale la pena notare che, mentre la documentazione di Python fornisce un caso d'uso (e probabilmente quello canonico) per questa eccezione, non ne esclude specificamente l'uso in altri scenari.

Considererei appropriato sollevare un'eccezione NotImplementedError se non hai ancora ignorato un metodo in una classe base (per soddisfare "l'interfaccia").

Un rapido controllo su Google suggerisce che le persone capiranno cosa intendi se usi l'eccezione in questo modo. Non ci sono effetti collaterali o conseguenze indesiderate che io conosca; il metodo genererà semplicemente un'eccezione se viene chiamato e genererà un'eccezione ben compresa da tutti.


La documentazione per Python 3 riflette questo utilizzo esatto:

Nelle classi di base definite dall'utente, i metodi astratti dovrebbero sollevare questa eccezione quando richiedono che le classi derivate abbiano la precedenza sul metodo o mentre la classe è in fase di sviluppo per indicare che è ancora necessario aggiungere l'implementazione reale . [Enfasi aggiunta]


+1, ma aggiungerei anche che per questo tipo di convenzione, un po 'di documentazione può fare molto. Come una nota di una riga in un wiki di sviluppo, un readme repo o una linea guida di stile - qualcosa del genere - che spiega a cosa usi questa eccezione.
Ben Lee

8

Questo sarà compreso, indipendentemente dal fatto che tu debba dipendere da convenzioni locali (di gruppo o aziendali). Si noti che ha meno senso nel contesto di TDD poiché il TEST dovrebbe essere ciò che determina che il metodo non è implementato.

La versione breve è: utilizzare se tu e il tuo team lo ritenete appropriato.


5
FWIW, Lanciare l'eccezione dovrebbe essere un buon modo per far fallire il test, se per qualche motivo è necessario forzare quel comportamento. (Sarebbe utile come parte di uno stub intellisense a definizione di metodo, per esempio.)
DougM

1

Sembra che di NotImplementedErrorsolito venga sollevato per lo sviluppo delle funzionalità di Python stesso, come il seguente:

@classmethod
def fromkeys(cls, iterable, v=None):
    # There is no equivalent method for counters because setting v=1
    # means that no element can have a count greater than one.
    raise NotImplementedError(
        'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')

documetation

fromkeys (iterable)

Questo metodo di classe non è implementato per gli oggetti Counter.

fonte

Collections.Counter.fromkeys

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.