fail - diseño de python: ¿por qué afirmar una afirmación y no una función?
assertion error python (4)
En Python, assert
es una declaración, y no una función. ¿Fue esta una decisión deliberada? ¿Hay alguna ventaja en assert
sea una declaración (y una palabra reservada) en lugar de una función?
Según the docs , assert expression1, expression2
se expande a
if __debug__:
if not expression1: raise AssertionError(expression2)
Los documentos también dicen que "el generador de código actual no emite código para una declaración de aserción cuando se solicita la optimización en tiempo de compilación". Sin conocer los detalles, parece necesario un caso especial para que esto sea posible. Pero luego, un caso especial también podría usarse para optimizar las llamadas ausentes a una función assert()
.
Si assert
fuera una función, podrías escribir:
assert(some_long_condition,
"explanation")
Pero como assert
es una afirmación, la tupla siempre evalúa como True
, y obtienes
SyntaxWarning: assertion is always true, perhaps remove parentheses?
La forma correcta de escribirlo es
assert some_long_condition, /
"explanation"
que es posiblemente menos bonito.
¿Hay alguna ventaja en afirmar que sea una declaración (y una palabra reservada) en lugar de una función?
- No se puede reasignar a una función de usuario, lo que significa que se puede desactivar efectivamente en el momento de la compilación, como señaló @mgilson.
- La evaluación del segundo parámetro opcional se aplaza hasta que / cuando la afirmación falle. Incómodo para hacer eso con funciones y argumentos de funciones (necesitaría pasar un lambda). No posponer la evaluación del segundo parámetro introduciría una sobrecarga adicional.
Además de las otras respuestas (y tipo de fuera de tema) un consejo. Para evitar el uso de barras diagonales inversas, puede usar la unión de líneas implícita dentro de paréntesis. ;-)
En lugar de:
assert some_long_condition, /
"explanation"
Podrías escribir:
assert some_long_condition, (
"explanation")
No soy un experto en Python, pero creo que el rendimiento es una de las principales razones.
si tenemos assert (expresión, explicación) como función, si la expresión es cara de evaluar, incluso si estamos en modo no depuración, Python necesita evaluar ambas expresiones para pasarla a la función assert.
Al expandir la afirmación, la declaración de expresión y explicación de hecho no se evalúa a menos que realmente se necesiten (cuando la depuración se evalúa como verdadera). Creo que es fundamental si queremos hacer que la afirmación no afecte el rendimiento cuando no es necesario (es decir, no hay un rendimiento alcanzado en el sistema de producción).
Una de las cosas maravillosas de assert
en python y en otros lenguajes (específicamente C) es que puedes eliminarlos para optimizar tu código simplemente agregando el #define
correcto (opcionalmente en la línea de comandos con cualquier compilador que haya usado alguna vez) u optimización banderas ( -O
en python). Si assert
convirtió en una función, esta característica sería imposible de agregar a python ya que no se sabe hasta el momento de ejecución si tiene la función de afirmación incorporada o la función del mismo nombre definida por el usuario.
También tenga en cuenta que en Python, las llamadas a funciones son razonablemente caras. Reemplazar en línea con el código if __debug__: ...
es probablemente mucho más eficiente que hacer una llamada a una función, lo que podría ser significativo si coloca una declaración de afirmación en una rutina de desempeño crítico.