Eu tenho lido algum código fonte e em vários lugares que eu já vi o uso assert
.
O que isso significa exatamente? Qual é o seu uso?
python
assert
assertions
Hossein
fonte
fonte
Respostas:
A
assert
declaração existe em quase todas as linguagens de programação. Ajuda a detectar problemas no início do seu programa, onde a causa é clara, e não mais tarde, como efeito colateral de alguma outra operação.Quando você faz...
... você está dizendo ao programa para testar essa condição e acionar imediatamente um erro se a condição for falsa.
No Python, é aproximadamente equivalente a isso:
Experimente no shell Python:
As asserções podem incluir uma mensagem opcional e você pode desabilitá-las ao executar o intérprete.
Para imprimir uma mensagem se a asserção falhar:
Você não usar parêntesis para chamar
assert
como uma função. É uma afirmação. Se você o fizer,assert(condition, message)
estará executando oassert
com uma(condition, message)
tupla como primeiro parâmetro.Quanto à desativação deles, quando executados
python
no modo otimizado, onde__debug__
estãoFalse
, as declarações de asserção serão ignoradas. Apenas passe a-O
bandeira:Veja aqui a documentação relevante.
fonte
if not condition: raise AssertError()
, por que devo usar assert? Existem condições sob as quais a afirmação é melhor do que apenas ser uma forma mais curta deif not condition
afirmação?if
). Leia os documentos para obter mais informações :)assert
, mas depois de ler todas as respostas, não tenho absolutamente nada que eu queira!Cuidado com os parênteses. Como foi apontado acima, no Python 3,
assert
ainda é uma afirmação ; portanto, por analogia comprint(..)
, pode-se extrapolar o mesmo paraassert(..)
ouraise(..)
mas você não deveria.Isso é importante porque:
não vai funcionar, ao contrário
A razão pela qual o primeiro não funcionará é que ele é
bool( (False, "Houston we've got a problem") )
avaliadoTrue
.Na declaração
assert(False)
, esses são apenas parênteses redundantesFalse
, que avaliam seu conteúdo. Mas comassert(False,)
os parênteses agora são uma tupla, e uma tupla não vazia é avaliadaTrue
em um contexto booleano.fonte
assert (2 + 2 = 5), "Houston we've got a problem"
deve ficar bem, sim?assert (2 + 2 = 5), "Houston we've got a problem"
não funcionará ... mas não tem nada a ver com a declaração assert, o que é bom. Sua condição não funcionará porque não é uma condição. Faltando um segundo=
.Como outras respostas observaram,
assert
é semelhante a lançar uma exceção se uma determinada condição não for verdadeira. Uma diferença importante é que as instruções assert são ignoradas se você compilar seu código com a opção de otimização-O
. A documentação diz queassert expression
pode ser melhor descrito como sendo equivalente aIsso pode ser útil se você quiser testar completamente seu código e liberar uma versão otimizada quando estiver feliz que nenhum dos seus casos de afirmação falhe - quando a otimização estiver ativada, a
__debug__
variável se tornará False e as condições deixarão de ser avaliadas. Esse recurso também pode capturá-lo se você confiar nas declarações e não perceber que elas desapareceram.fonte
if Not Error: raise Exception(“ this is a error”)
? Dessa forma, o programa ainda vai mostrar a origem do erro, quando o usuário executa-lo ..assert
instrução? A suposição aqui é que, quando o programa é lançado para o usuário final, você está usando o sinalizador -O, assumindo que todos os erros foram removidos. Portanto, qualquer erro ou falha no programa deve-se à entrada no programa que é válida de acordo com o contrato, mas não pode ser tratada pelo programa. Portanto, ele deve alertar o usuário como tal.O objetivo de uma asserção no Python é informar os desenvolvedores sobre erros irrecuperáveis em um programa.
As asserções não pretendem sinalizar as condições de erro esperadas, como “arquivo não encontrado”, em que um usuário pode executar uma ação corretiva (ou apenas tentar novamente).
Outra maneira de ver isso é dizer que as asserções são auto-verificações internas no seu código. Eles funcionam declarando algumas condições como impossíveis no seu código. Se essas condições não se mantiverem, isso significa que há um erro no programa.
Se o seu programa estiver livre de erros, essas condições nunca ocorrerão. Mas se um deles faz ocorrer o programa irá falhar com um erro de declaração dizendo exatamente qual condição “impossível” foi acionado. Isso torna muito mais fácil rastrear e corrigir erros em seus programas.
Aqui está um resumo de um tutorial sobre as afirmações de Python que escrevi:
fonte
assert
declaração e quando usá-la. Estou tentando entender vários termos que você introduziu no artigo.assert store.product_exists(product_id), 'Unknown product id'
não é uma boa prática, porque se a depuração for desativada, ouser
mesmo se nãoadmin
for capaz de excluir o produto. Você consideraassert user.is_admin()
umunrecoverable
erro? Por que isso não é umself-check
?assert statement
,price
também não pode ser considerada uma entrada do usuário? Por que você consideraassert user.is_admin()
validação de dados, mas nãoassert price
?Outros já lhe deram links para a documentação.
Você pode tentar o seguinte em um shell interativo:
A primeira declaração não faz nada, enquanto a segunda gera uma exceção. Esta é a primeira dica: asserts são úteis para verificar condições que devem ser verdadeiras em uma determinada posição do seu código (geralmente, o início (pré-condições) e o final de uma função (pós-condições)).
Afirmações são realmente altamente ligadas à programação por contrato, o que é uma prática de engenharia muito útil:
http://en.wikipedia.org/wiki/Design_by_contract .
fonte
Dos documentos:
Aqui você pode ler mais: http://docs.python.org/release/2.5.2/ref/assert.html
fonte
A declaração assert possui duas formas.
A forma simples,,
assert <expression>
é equivalente aO formulário estendido,,
assert <expression1>, <expression2>
é equivalente afonte
As asserções são uma maneira sistemática de verificar se o estado interno de um programa é o esperado pelo programador, com o objetivo de detectar bugs. Veja o exemplo abaixo.
fonte
Aqui está um exemplo simples, salve-o no arquivo (digamos b.py)
e o resultado quando
$python b.py
fonte
se a declaração após a afirmação for verdadeira, o programa continuará, mas se a declaração após a afirmação for falsa, o programa emitirá um erro. Simples assim.
por exemplo:
fonte
A
assert
declaração existe em quase todas as linguagens de programação. Ajuda a detectar problemas no início do seu programa, onde a causa é clara, e não mais tarde, como efeito colateral de alguma outra operação. Eles sempre esperam umaTrue
condição.Quando você faz algo como:
Você está dizendo ao programa para testar essa condição e acionar imediatamente um erro, se for falso.
Em Python,
assert
expressão é equivalente a:Você pode usar a expressão estendida para passar uma mensagem opcional :
Experimente no intérprete Python:
Existem algumas ressalvas a serem vistas antes de usá-las principalmente para aqueles que consideram alternar entre as declarações
assert
eif
. O objetivo a ser usadoassert
é em ocasiões em que o programa verifica uma condição e retorna um valor que deve interromper o programa imediatamente, em vez de usar uma maneira alternativa de contornar o erro:1. Parênteses
Como você deve ter notado, a
assert
declaração usa duas condições. Portanto, não use parênteses para incluí-los como um conselho óbvio. Se você faz como:Exemplo:
Você estará executando o
assert
com a(condition, message)
que representa uma tupla como o primeiro parâmetro, e isso acontece porque a tupla não vazia no Python é sempreTrue
. No entanto, você pode fazer separadamente sem problemas:Exemplo:
2. Finalidade de depuração
Se você está se perguntando sobre quando usar a
assert
declaração. Veja um exemplo usado na vida real:* Quando seu programa tende a controlar cada parâmetro inserido pelo usuário ou qualquer outra coisa:
* Outro caso é na matemática quando 0 ou não positivo como coeficiente ou constante em uma determinada equação:
* ou mesmo um exemplo simples de implementação booleana:
3. Processamento ou validação de dados
A maior importância é não confiar na
assert
instrução para executar o processamento ou a validação de dados, pois essa instrução pode ser desativada na inicialização do Python com-O
ou-OO
flag - ou seja, valores 1, 2 e 0 (como padrão), respectivamente - ouPYTHONOPTIMIZE
variável de ambiente .Valor 1:
* afirmações estão desativadas;
* arquivos de bytecode são gerados usando
.pyo
extensão em vez de.pyc
;*
sys.flags.optimize
está definido como 1 (True
);* e,
__debug__
está definido comoFalse
;Valor 2: desativa mais uma coisa
* docstrings estão desabilitadas;
Portanto, o uso da
assert
instrução para validar um tipo de dado esperado é extremamente perigoso, implicando até alguns problemas de segurança. Então, se você precisar validar alguma permissão, recomendoraise AuthError
. Como efetivo pré-condicional, umassert
é comumente usado por programadores em bibliotecas ou módulos que não têm um usuário para interagir diretamente.fonte
Como resumido de forma concisa no C2 Wiki :
Você pode usar uma
assert
instrução para documentar sua compreensão do código em um ponto específico do programa. Por exemplo, você pode documentar suposições ou garantias sobre entradas (pré-condições), estado do programa (invariantes) ou saídas (pós-condições).Se sua afirmação falhar, este é um alerta para você (ou seu sucessor) de que seu entendimento do programa estava errado quando você o escreveu e que provavelmente contém um bug.
Para obter mais informações, John Regehr tem um maravilhoso post sobre o uso de asserções , que também se aplica à
assert
declaração Python .fonte
Se você quiser saber exatamente o que uma função reservada faz no python, digite
help(enter_keyword)
Certifique-se de digitar uma palavra-chave reservada como uma sequência de caracteres.
fonte
O Python assert é basicamente um auxiliar de depuração que testa a condição de autoverificação interna do seu código. A declaração torna a depuração realmente fácil quando o seu código entra em casos extremos impossíveis. Afirme verificar esses casos impossíveis.
Digamos que haja uma função para calcular o preço do item após o desconto:
aqui, o preço com desconto nunca pode ser menor que 0 e maior que o preço real. Portanto, caso a condição acima seja violada, a declaração gera um erro de declaração, que ajuda o desenvolvedor a identificar que algo impossível aconteceu.
Espero que ajude :)
fonte
assert
é útil em um contexto de depuração, mas não deve ser invocado fora de um contexto de depuração.Minha breve explicação é:
assert
aumentaAssertionError
se a expressão for falsa, caso contrário, apenas continua o código, e se houver uma vírgula, seja como forAssertionError: whatever after comma
, e o código é como:raise AssertionError(whatever after comma)
Um tutorial relacionado sobre isso:
fonte
assert
, mas não quando usar (ou não usar) umassert
; também observando que umassert
pode ser desativado se__debug__
forFalse
seria útil.No Pycharm, se você usar
assert
junto comisinstance
para declarar o tipo de um objeto, ele permitirá que você acesse os métodos e atributos do objeto pai enquanto estiver codificando, ele será concluído automaticamente.Por exemplo, digamos que
self.object1.object2
seja umMyClass
objeto.fonte
Conforme escrito em outras respostas, as
assert
instruções são usadas para verificar o estado do programa em um determinado momento.Não repetirei o que foi dito sobre mensagens, parênteses ou
-O
opção e__debug__
constante associados . Consulte também o documento para obter informações em primeira mão. Vou me concentrar na sua pergunta: de que serveassert
? Mais precisamente, quando (e quando não) deve-se usarassert
?As
assert
instruções são úteis para depurar um programa, mas são desencorajadas a verificar a entrada do usuário. Eu uso a seguinte regra geral: mantenha asserções para detectar uma situação que isso não deve acontecer . Uma entrada do usuário pode estar incorreta, por exemplo, uma senha muito curta, mas essa não é uma isso não deve acontecer . Se o diâmetro de um círculo não for duas vezes maior que seu raio, você está nesse caso.O uso mais interessante, em minha opinião,
assert
é inspirado na programação por contrato, conforme descrito por B. Meyer em [Construção de software orientada a objetos] ( https://www.eiffel.org/doc/eiffel/Object-Oriented_Software_Construction% 2C_2nd_Edition ) e implementado na [linguagem de programação Eiffel] ( https://en.wikipedia.org/wiki/Eiffel_(programming_language) ). Você não pode emular completamente a programação por contrato usando aassert
declaração, mas é interessante manter a intenção.Aqui está um exemplo. Imagine que você precise escrever uma
head
função (como a [head
função em Haskell] ( http://www.zvon.org/other/haskell/Outputprelude/head_f.html )). A especificação que você recebe é: "se a lista não estiver vazia, retorne o primeiro item de uma lista". Veja as seguintes implementações:E
(Sim, isso pode ser escrito como
return xs[0] if xs else None
, mas esse não é o ponto) .Se a lista não estiver vazia, ambas as funções terão o mesmo resultado e este resultado está correto:
Portanto, ambas as implementações estão (espero) corretas. Eles diferem quando você tenta obter o item principal de uma lista vazia:
Mas:
Novamente, ambas as implementações estão corretas, porque ninguém deve passar uma lista vazia para essas funções (estamos fora da especificação ). Essa é uma ligação incorreta, mas se você fizer essa ligação, tudo poderá acontecer. Uma função gera uma exceção, a outra retorna um valor especial. O mais importante é: não podemos confiar nesse comportamento . Se
xs
estiver vazio, isso funcionará:Mas isso irá travar o programa:
Para evitar algumas surpresas, gostaria de saber quando estou passando algum argumento inesperado para uma função. Em outras palavras: eu gostaria de saber quando o comportamento observável não é confiável, porque depende da implementação, não da especificação. Obviamente, eu posso ler a especificação, mas os programadores nem sempre leem com atenção os documentos.
Imagine se eu tivesse uma maneira de inserir a especificação no código para obter o seguinte efeito: quando eu viole a especificação, por exemplo, passando uma lista vazia para
head
, recebo um aviso. Isso seria uma grande ajuda para escrever um programa correto (ou seja, compatível com a especificação). E é aí queassert
entra em cena:E
Agora, temos:
E:
Observe que
head1
lança umAssertionError
, não umIndexError
. Isso é importante porque umAssertionError
não é nenhum erro de execução: ele sinaliza uma violação da especificação. Eu queria um aviso, mas recebo um erro. Felizmente, posso desativar a verificação (usando a-O
opção), mas por minha conta e risco. Vou fazê-lo um acidente é realmente caro, e espero o melhor. Imagine que meu programa está incorporado em uma nave espacial que viaja através de um buraco negro. Desabilitarei as afirmações e espero que o programa seja robusto o suficiente para não travar o maior tempo possível.Este exemplo foi apenas sobre pré-condições, você pode usar
assert
para verificar pós-condições (o valor de retorno e / ou o estado) e invariantes (estado de uma classe). Observe que a verificação de pós-condições e invariantesassert
pode ser complicada:Você não terá algo tão sofisticado quanto o Eiffel, mas, no entanto, pode melhorar a qualidade geral de um programa.
Para resumir, a
assert
declaração é uma maneira conveniente de detectar uma situação que não deve acontecer . Violações da especificação (por exemplo, passar uma lista vazia parahead
) são de primeira classe; isso não deve ocorrer em situações. Portanto, embora aassert
declaração possa ser usada para detectar qualquer situação inesperada, é uma maneira privilegiada de garantir que a especificação seja cumprida. Depois de inserirassert
instruções no código para representar a especificação, podemos esperar que você tenha melhorado a qualidade do programa, porque argumentos incorretos, valores de retorno incorretos, estados incorretos de uma classe ... serão relatados.fonte
formato: assert Expression [, argumentos] Quando assert encontra uma instrução, o Python avalia a expressão.Se a instrução não for verdadeira, uma exceção será gerada (assertionError). Se a asserção falhar, o Python usará ArgumentExpression como argumento para o AssertionError. As exceções AssertionError podem ser capturadas e manipuladas como qualquer outra exceção usando a instrução try-except, mas se não forem tratadas, elas encerrarão o programa e produzirão um retorno. Exemplo:
Quando o código acima é executado, ele produz o seguinte resultado:
fonte
Pode ser usado para garantir que os parâmetros sejam passados na chamada de função.
fonte
if not user_key: raise ValueError()
check últimos 2 parágrafos aqui: wiki.python.org/moin/UsingAssertionsEffectivelyassert
não deve ser usado para validação de entrada porque a validação será removida, se__debug__
estiverFalse
. Também usar asserções para fins de não depuração pode fazer com que as pessoas capturem osAssertionError
s resultantes , o que pode dificultar a depuração em vez de menos.fonte
Basicamente, o significado da palavra-chave assert é que, se a condição não for verdadeira, ela será processada através de um erro de asserção, caso contrário, continuará, por exemplo, em python.
código-1
RESULTADO:
código-2
RESULTADO:
fonte
assert
, mas não responde quando usar (ou não usar) umassert
.