Bene, questa è una domanda aperta e ho due aspetti che voglio toccare: quando aggiungere asserzioni e come scrivere i messaggi di errore.
Scopo
Per spiegarlo a un principiante, le asserzioni sono dichiarazioni che possono generare errori, ma non le intercetterai. E normalmente non dovrebbero essere allevati, ma nella vita reale a volte vengono sollevati comunque. E questa è una situazione grave, dalla quale il codice non può recuperare, quello che chiamiamo un "errore fatale".
Successivamente, è per "scopi di debug", che, sebbene corretto, sembra molto sprezzante. Mi piace la formulazione "dichiaranti invarianti, che non dovrebbe mai essere violata", anche se funziona in modo diverso su diversi principianti ... Alcuni "capiscono", e altri o non trovano alcun uso o sostituiscono le normali eccezioni, o addirittura controllare il flusso con esso.
Stile
In Python assert
è un'affermazione, non una funzione! (Ricorda assert(False, 'is true')
che non rilancerà. Ma, tenendo fuori questo:
Quando e come scrivere il "messaggio di errore" facoltativo?
Ciò si applica in modo concreto ai framework di unit test, che spesso hanno molti metodi dedicati per fare affermazioni ( assertTrue(condition)
,assertFalse(condition), assertEqual(actual, expected)
ecc.). Spesso forniscono anche un modo per commentare l'affermazione.
Nel codice usa e getta potresti fare a meno dei messaggi di errore.
In alcuni casi, non c'è nulla da aggiungere all'asserzione:
def dump (qualcosa): assert isinstance (qualcosa, Dumpable) # ...
Ma a parte questo, un messaggio è utile per la comunicazione con altri programmatori (che a volte sono utenti interattivi del tuo codice, ad esempio in Ipython / Jupyter ecc.).
Fornisci loro informazioni, non solo dettagli di implementazione interni.
invece di:
assert meaningless_identifier <= MAGIC_NUMBER_XXX, 'meaningless_identifier is greater than MAGIC_NUMBER_XXX!!!'
Scrivi:
assert meaningless_identifier > MAGIC_NUMBER_XXX, 'reactor temperature above critical threshold'
o forse anche:
assert meaningless_identifier > MAGIC_NUMBER_XXX, f'reactor temperature({meaningless_identifier }) above critical threshold ({MAGIC_NUMBER_XXX})'
Lo so, lo so - questo non è un caso per un'asserzione statica, ma voglio indicare il valore informativo del messaggio.
Messaggio negativo o positivo?
Questo può essere controverso, ma mi fa male leggere cose come:
assert a == b, 'a is not equal to b'
queste sono due cose contraddittorie scritte l'una accanto all'altra. Quindi ogni volta che ho un'influenza sulla base di codice, spingo per specificare ciò che vogliamo, usando verbi extra come 'must' e 'should', e non dire ciò che non vogliamo.
asserire a == b, 'a deve essere uguale a b'
Quindi, anche ottenere AssertionError: a must be equal to b
è leggibile e l'istruzione appare logica nel codice. Inoltre, puoi ottenere qualcosa da esso senza leggere il traceback (che a volte non può nemmeno essere disponibile).