¿Cómo desactivo las afirmaciones en Python?
Es decir, si una afirmación falla, no quiero que arroje una AssertionError
, sino que continúe.
¿Cómo puedo hacer eso?
Respuestas:
¿Cómo desactivo las afirmaciones en Python?
Hay varios enfoques que afectan a un solo proceso, el entorno o una sola línea de código.
Demuestro cada uno.
El uso de la -O
bandera (O mayúscula) deshabilita todas las declaraciones de aserción en un proceso.
Por ejemplo:
$ python -Oc "assert False"
$ python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
Tenga en cuenta que por deshabilitar me refiero a que tampoco ejecuta la expresión que le sigue:
$ 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
También puede usar una variable de entorno para establecer esta bandera.
Esto afectará a todos los procesos que utilizan o heredan el entorno.
Por ejemplo, en Windows, configurar y luego borrar la variable de entorno:
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
Lo mismo en Unix (usando set y unset para la funcionalidad respectiva)
Continúas tu pregunta:
si una aserción falla, no quiero que arroje un AssertionError, sino que continúe.
Si desea que el código no se ejecute, puede asegurarse de que el flujo de control no llegue a la aserción, por ejemplo:
if False:
assert False, "we know this fails, but we don't get here"
o puede detectar el error de aserción:
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')
y continuará desde el punto en que manejó el AssertionError
.
Una afirmación como esta:
assert expression #, optional_message
Es equivalente a
if __debug__:
if not expression: raise AssertionError #(optional_message)
Y,
la variable incorporada
__debug__
estáTrue
en circunstancias normales,False
cuando se solicita la optimización (opción de línea de comando-O
).
y además
Las asignaciones a
__debug__
son ilegales. El valor de la variable incorporada se determina cuando se inicia el intérprete.
De los documentos de uso:
Active las optimizaciones básicas. Esto cambia la extensión del nombre de archivo para archivos compilados (código de bytes) de .pyc a .pyo. Consulte también PYTHONOPTIMIZAR.
y
Si se establece en una cadena no vacía, equivale a especificar la
-O
opción. Si se establece en un número entero, equivale a especificar-O
varias veces.
if False: assert False
) o puede detectar el error de afirmación. Esas son tus elecciones. Se actualizó la respuesta para abordar su pregunta.
foo()
y afirmaciones Desconexión: with skip_assertion(): foo()
. El beneficio de esto es que no tengo que agregar otra bandera en la función
Assert
objetos con Pass
objetos). Un administrador de contexto no funcionaría directamente para eso, pero podría tener algún tipo de mecanismo que usara funciones decoradas de esa manera. Independientemente, no lo recomiendo. Sospecho que su razón para querer hacerlo es que está llamando a un código que no controla y obteniendo AssertionErrors. Si es así, probablemente necesite encontrar una solución diferente.
Llame a Python con la bandera -O:
test.py:
assert(False)
print 'Done'
Salida:
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
Las dos respuestas ya dadas son válidas (llame a Python con -O
o -OO
en la línea de comando).
Aquí está la diferencia entre ellos:
-O
Active las optimizaciones básicas. Esto cambia la extensión del nombre de archivo para archivos compilados (código de bytes) de .pyc a .pyo.
-OO
Descarte las cadenas de documentos además de las -O
optimizaciones.
(De la documentación de Python )
Utilizar python -O
:
$ python -O
>>> assert False
>>>
NO debe deshabilitar (la mayoría) de las afirmaciones. Detectan errores inesperados cuando la atención está en otra parte. Consulte la Regla 5 en "El poder de diez" .
En su lugar, proteja algunas comprobaciones de afirmaciones caras con algo como:
import logging
logger = logging.getLogger(__name__)
if logger.getEffectiveLevel() < logging.DEBUG:
ok = check_expensive_property()
assert ok, 'Run !'
Una forma de mantener afirmaciones importantes y permitir que las assert
declaraciones se optimicen es elevándolas dentro de una declaración de selección:
if foo_is_broken():
raise AssertionError('Foo is broken!')
__debug__
en False pero eso no está permitido.