Como desativo asserções em Python?
Ou seja, se uma afirmação falhar, não quero que ela lance um AssertionError
, mas continue.
Como faço isso?
Respostas:
Como desativo asserções em Python?
Existem várias abordagens que afetam um único processo, o ambiente ou uma única linha de código.
Eu demonstro cada um.
Usar o -O
sinalizador (maiúsculo) desativa todas as instruções assert em um processo.
Por exemplo:
$ python -Oc "assert False"
$ python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
Observe que por desativar quero dizer que também não executa a expressão que o segue:
$ python -Oc "assert 1/0"
$ python -c "assert 1/0"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
Você também pode usar uma variável de ambiente para definir esse sinalizador.
Isso afetará todos os processos que usam ou herdam o ambiente.
Por exemplo, no Windows, configurar e limpar a variável de ambiente:
C:\>python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
C:\>SET PYTHONOPTIMIZE=TRUE
C:\>python -c "assert False"
C:\>SET PYTHONOPTIMIZE=
C:\>python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
Mesmo no Unix (usando definir e não definir para a respectiva funcionalidade)
Você continua sua pergunta:
se uma afirmação falhar, não quero que ela lance um AssertionError, mas continue.
Se você quiser que o código não seja executado, você pode garantir que o fluxo de controle não alcance a asserção, por exemplo:
if False:
assert False, "we know this fails, but we don't get here"
ou você pode detectar o erro de asserção:
try:
assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
print(repr(e))
que imprime:
AssertionError('this code runs, fails, and the exception is caught')
e você continuará a partir do ponto em que manipulou o AssertionError
.
A partir da assert
documentação :
Uma declaração assert como esta:
assert expression #, optional_message
É equivalente a
if __debug__:
if not expression: raise AssertionError #(optional_message)
E,
a variável embutida
__debug__
estáTrue
em circunstâncias normais,False
quando a otimização é solicitada (opção de linha de comando-O
).
e mais
As atribuições a
__debug__
são ilegais. O valor da variável embutida é determinado quando o interpretador é iniciado.
Dos documentos de uso:
Ative as otimizações básicas. Isso muda a extensão do nome do arquivo para arquivos compilados (bytecode) de .pyc para .pyo. Veja também PYTHONOPTIMIZE.
e
Se for definido como uma string não vazia, é equivalente a especificar a
-O
opção. Se definido como um inteiro, é equivalente a especificar-O
várias vezes.
if False: assert False
) ou pode capturar o erro de declaração. Essas são suas escolhas. Atualizada a resposta para responder à sua pergunta.
foo()
e afirmações de comutação off: with skip_assertion(): foo()
. A vantagem disso é que não preciso adicionar outro sinalizador na função
Assert
objetos por Pass
objetos). Um gerenciador de contexto não funcionaria diretamente para isso, mas você poderia ter algum tipo de mecanismo que usasse funções decoradas dessa maneira. Apesar de tudo, não o recomendo. Suspeito que você queira fazer isso por estar chamando um código que não controla e obtendo AssertionErrors. Em caso afirmativo, você provavelmente precisará encontrar uma solução diferente.
Chame Python com a sinalização -O:
test.py:
assert(False)
print 'Done'
Resultado:
C:\temp\py>C:\Python26\python.exe test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
assert(False)
AssertionError
C:\temp\py>C:\Python26\python.exe -O test.py
Done
Ambas as respostas já fornecidas são válidas (chame Python com -O
ou -OO
na linha de comando).
Aqui está a diferença entre eles:
-O
Ative as otimizações básicas. Isso muda a extensão do nome do arquivo para arquivos compilados (bytecode) de .pyc para .pyo.
-OO
Descarte docstrings além das -O
otimizações.
(Da documentação do Python )
Use python -O
:
$ python -O
>>> assert False
>>>
Você NÃO deve desabilitar (a maioria) asserções. Eles detectam erros imprevistos quando a atenção está em outro lugar. Consulte a Regra 5 em "A potência de dez" .
Em vez disso, guarde algumas verificações de afirmações caras por algo como:
import logging
logger = logging.getLogger(__name__)
if logger.getEffectiveLevel() < logging.DEBUG:
ok = check_expensive_property()
assert ok, 'Run !'
Uma maneira de manter afirmações importantes e permitir que as assert
afirmações sejam otimizadas é levantando-as em uma instrução de seleção:
if foo_is_broken():
raise AssertionError('Foo is broken!')
__debug__
como False, mas isso não é permitido.