Bem, essa é uma pergunta em aberto e tenho dois aspectos nos quais quero abordar: quando adicionar asserções e como escrever as mensagens de erro.
Objetivo
Para explicar isso para um iniciante - asserções são declarações que podem gerar erros, mas você não as pegará. E eles normalmente não devem ser criados, mas na vida real às vezes são criados de qualquer maneira. E essa é uma situação séria, da qual o código não pode se recuperar, do que chamamos de 'erro fatal'.
Em seguida, é para 'fins de depuração', que, embora corretos, parece muito desdenhoso. Gosto mais da formulação 'declarar invariantes, que nunca deve ser violada', embora funcione de maneira diferente em iniciantes diferentes ... Alguns 'apenas entendem', e outros não encontram utilidade ou substituem exceções normais, ou mesmo controlar o fluxo com ele.
Estilo
Em Python, assert
é uma declaração, não uma função! (lembre- assert(False, 'is true')
se que não aumentará. Mas, tendo isso fora do caminho:
Quando e como escrever a 'mensagem de erro' opcional?
Isso se aplica de fato a estruturas de teste de unidade, que geralmente têm muitos métodos dedicados para fazer asserções ( assertTrue(condition)
, assertFalse(condition), assertEqual(actual, expected)
etc.). Eles geralmente também fornecem uma maneira de comentar a afirmação.
No código descartável, você pode ficar sem as mensagens de erro.
Em alguns casos, não há nada a acrescentar à asserção:
def dump (algo): assert isinstance (algo, Dumpable) # ...
Além disso, uma mensagem é útil para comunicação com outros programadores (que às vezes são usuários interativos do seu código, por exemplo, no Ipython / Jupyter etc.).
Forneça informações, não apenas vaze detalhes de implementação interna.
ao invés de:
assert meaningless_identifier <= MAGIC_NUMBER_XXX, 'meaningless_identifier is greater than MAGIC_NUMBER_XXX!!!'
Escreva:
assert meaningless_identifier > MAGIC_NUMBER_XXX, 'reactor temperature above critical threshold'
ou talvez até:
assert meaningless_identifier > MAGIC_NUMBER_XXX, f'reactor temperature({meaningless_identifier }) above critical threshold ({MAGIC_NUMBER_XXX})'
Eu sei, eu sei - esse não é um caso de afirmação estática, mas quero apontar para o valor informativo da mensagem.
Mensagem negativa ou positiva?
Isso pode ser absurdo, mas me dói ler coisas como:
assert a == b, 'a is not equal to b'
estas são duas coisas contraditórias escritas próximas uma da outra. Portanto, sempre que influencio a base de código, insisto em especificar o que queremos, usando verbos extras como 'must' e 'should', sem dizer o que não queremos.
afirme a == b, 'a deve ser igual a b'
Então, get AssertionError: a must be equal to b
também é legível e a instrução parece lógica no código. Além disso, você pode obter algo sem ler o traceback (que às vezes nem pode estar disponível).