He estado leyendo un código fuente y en varios lugares he visto el uso de assert
.
¿Qué significa exactamente? ¿Cuál es su uso?
python
assert
assertions
Hossein
fuente
fuente
Respuestas:
La
assert
declaración existe en casi todos los lenguajes de programación. Ayuda a detectar problemas temprano en su programa, donde la causa es clara, y no más tarde como un efecto secundario de alguna otra operación.Cuando tu lo hagas...
... le está diciendo al programa que pruebe esa condición e inmediatamente active un error si la condición es falsa.
En Python, es más o menos equivalente a esto:
Pruébelo en el shell de Python:
Las aserciones pueden incluir un mensaje opcional, y puede deshabilitarlas al ejecutar el intérprete.
Para imprimir un mensaje si la afirmación falla:
No , no utilizar paréntesis para llamar
assert
como una función. Es una declaración. Si lo hacesassert(condition, message)
, estarás ejecutandoassert
con una(condition, message)
tupla como primer parámetro.En cuanto a deshabilitarlos, cuando se ejecuta
python
en modo optimizado, donde__debug__
estáFalse
, las declaraciones de aserción serán ignoradas. Solo pasa la-O
bandera:Vea aquí para la documentación relevante.
fuente
if not condition: raise AssertError()
, ¿por qué debería usar afirmar? ¿Hay alguna condición bajo la cual laif not condition
afirmación sea mejor además de ser una forma más corta de declaración?if
). Lea los documentos para obtener más información :)assert
, pero después de leer todas las respuestas, no obtuve nada que quiero!Cuidado con los paréntesis. Como se ha señalado anteriormente, en Python 3,
assert
sigue siendo una declaración , por analogía conprint(..)
, uno puede extrapolar lo mismoassert(..)
aoraise(..)
pero no debería.Esto es importante porque:
no funcionará, a diferencia de
La razón por la que el primero no funcionará es porque se
bool( (False, "Houston we've got a problem") )
evalúaTrue
.En la declaración
assert(False)
, estos son solo paréntesis redundantesFalse
, que evalúan su contenido. Pero conassert(False,)
los paréntesis ahora son una tupla, y una tupla no vacía se evalúaTrue
en un contexto booleano.fuente
assert (2 + 2 = 5), "Houston we've got a problem"
debería estar bien, ¿sí?assert (2 + 2 = 5), "Houston we've got a problem"
no funcionará ... pero no tiene nada que ver con la declaración de aserción, lo cual está bien. Su condición no funcionará porque no es una condición. Perder un segundo=
.Como han señalado otras respuestas,
assert
es similar a lanzar una excepción si una condición dada no es verdadera. Una diferencia importante es que las declaraciones de aserción se ignoran si compila su código con la opción de optimización-O
. La documentación dice queassert expression
puede describirse mejor como equivalente aEsto puede ser útil si desea probar a fondo su código, luego lanzar una versión optimizada cuando esté satisfecho de que ninguno de sus casos de afirmación falle: cuando la optimización está activada, la
__debug__
variable se convierte en False y las condiciones dejarán de evaluarse. Esta característica también puede atraparte si confías en las afirmaciones y no te das cuenta de que han desaparecido.fuente
if Not Error: raise Exception(“ this is a error”)
? De esa manera, el programa seguirá mostrando la fuente del error, cuando el usuario lo ejecute ..assert
declaración? La suposición aquí es que cuando el programa se lanza al usuario final, está utilizando el indicador -O, suponiendo que se han eliminado todos los errores. Por lo tanto, cualquier error o bloqueo del programa se debe a la entrada al programa que es válida según el contrato, pero no puede ser manejada por el programa. Por lo tanto, debe alertar al usuario como tal.El objetivo de una afirmación en Python es informar a los desarrolladores sobre errores irrecuperables en un programa.
Las afirmaciones no pretenden indicar condiciones de error esperadas, como "archivo no encontrado", donde un usuario puede tomar medidas correctivas (o simplemente intentarlo de nuevo).
Otra forma de verlo es decir que las aserciones son autocomprobaciones internas en su código. Funcionan declarando algunas condiciones como imposibles en su código. Si estas condiciones no se cumplen, significa que hay un error en el programa.
Si su programa está libre de errores, estas condiciones nunca ocurrirán. Pero si uno de ellos lo hace aparecer el programa se bloquea con un error de aserción que le dice exactamente lo que se desencadenó condición de “imposible”. Esto hace que sea mucho más fácil rastrear y corregir errores en sus programas.
Aquí hay un resumen de un tutorial sobre las afirmaciones de Python que escribí:
fuente
assert
declaración y cuándo usar esto. Estoy tratando de entender una serie de términos que introdujo en el artículo.assert store.product_exists(product_id), 'Unknown product id'
no es una buena práctica, porque si la depuración está desactivada,user
incluso si noadmin
se podrá eliminar el producto. ¿Lo considerasassert user.is_admin()
como ununrecoverable
error? ¿Por qué esto no es unself-check
?assert statement
, ¿noprice
puede considerarse también una entrada del usuario? ¿Por qué considerasassert user.is_admin()
como validación de datos pero noassert price
?Otros ya le han dado enlaces a la documentación.
Puede probar lo siguiente en un shell interactivo:
La primera declaración no hace nada, mientras que la segunda plantea una excepción. Esta es la primera pista: las afirmaciones son útiles para verificar las condiciones que deberían ser ciertas en una posición dada de su código (generalmente, el principio (condiciones previas) y el final de una función (condiciones posteriores)).
Las afirmaciones en realidad están muy ligadas a la programación por contrato, lo cual es una práctica de ingeniería muy útil:
http://en.wikipedia.org/wiki/Design_by_contract .
fuente
De documentos:
Aquí puede leer más: http://docs.python.org/release/2.5.2/ref/assert.html
fuente
La afirmación tiene dos formas.
La forma simple
assert <expression>
, es equivalente aLa forma extendida
assert <expression1>, <expression2>
, es equivalente afuente
Las afirmaciones son una forma sistemática de verificar que el estado interno de un programa es el esperado por el programador, con el objetivo de detectar errores. Vea el ejemplo a continuación.
fuente
Aquí hay un ejemplo simple, guarde esto en un archivo (digamos b.py)
y el resultado cuando
$python b.py
fuente
si la declaración después de afirmar es verdadera, el programa continúa, pero si la declaración después de afirmar es falsa, entonces el programa da un error. Simple como eso.
p.ej:
fuente
La
assert
declaración existe en casi todos los lenguajes de programación. Ayuda a detectar problemas temprano en su programa, donde la causa es clara, y no más tarde como un efecto secundario de alguna otra operación. Siempre esperan unaTrue
condición.Cuando haces algo como:
Le está diciendo al programa que pruebe esa condición e inmediatamente active un error si es falso.
En Python,
assert
expresión , es equivalente a:Puede usar la expresión extendida para pasar un mensaje opcional :
Pruébelo en el intérprete de Python:
Hay algunas advertencias para ver antes de usarlas principalmente para aquellos que consideran alternar entre las declaraciones
assert
yif
. El objetivo de usarassert
es en ocasiones cuando el programa verifica una condición y devuelve un valor que debería detener el programa de inmediato en lugar de tomar alguna forma alternativa para evitar el error:1. paréntesis
Como habrás notado, la
assert
declaración usa dos condiciones. Por lo tanto, no use paréntesis para englobarlos como un consejo obvio. Si haces tal como:Ejemplo:
Ejecutará el
assert
con un(condition, message)
que representa una tupla como primer parámetro, y esto sucede porque la tupla no vacía en Python siempreTrue
es así . Sin embargo, puede hacerlo por separado sin problema:Ejemplo:
2. Propósito de depuración
Si se pregunta cuándo usar la
assert
declaración. Tome un ejemplo usado en la vida real:* Cuando su programa tiende a controlar cada parámetro ingresado por el usuario o cualquier otra cosa:
* Otro caso es en matemáticas cuando 0 o no positivo como coeficiente o constante en una ecuación determinada:
* o incluso un simple ejemplo de implementación booleana:
3. Procesamiento de datos o validación de datos
La mayor importancia es no confiar en la
assert
declaración para ejecutar el procesamiento de datos o la validación de datos, ya que esta declaración se puede desactivar en la inicialización de Python con-O
o-OO
flag, es decir, el valor 1, 2 y 0 (por defecto), respectivamente, oPYTHONOPTIMIZE
la variable de entorno .Valor 1:
* las afirmaciones están deshabilitadas;
* los archivos de bytecode se generan usando la
.pyo
extensión en lugar de.pyc
;*
sys.flags.optimize
se establece en 1 (True
);* y,
__debug__
se establece enFalse
;Valor 2: deshabilita una cosa más
* las cadenas de documentos están deshabilitadas;
Por lo tanto, usar la
assert
declaración para validar un tipo de datos esperados es extremadamente peligroso, lo que implica incluso algunos problemas de seguridad. Entonces, si necesita validar algún permiso, le recomiendo en suraise AuthError
lugar. Como precondicional efectivo, losassert
programadores usan comúnmente un en bibliotecas o módulos que no tienen un usuario que interactúe directamente.fuente
Como se resume de manera concisa en C2 Wiki :
Puede usar una
assert
declaración para documentar su comprensión del código en un punto particular del programa. Por ejemplo, puede documentar supuestos o garantías sobre entradas (condiciones previas), estado del programa (invariantes) o salidas (condiciones posteriores).Si alguna vez falla su afirmación, esta es una alerta para usted (o su sucesor) de que su comprensión del programa era incorrecta cuando lo escribió y que probablemente contenga un error.
Para obtener más información, John Regehr tiene una maravillosa publicación de blog sobre el uso de aserciones , que también se aplica a la
assert
declaración de Python .fuente
Si alguna vez quieres saber exactamente qué hace una función reservada en Python, escribe
help(enter_keyword)
Asegúrese de que si ingresa una palabra clave reservada, la ingresa como una cadena.
fuente
Python afirmar es básicamente una ayuda de depuración que prueba la condición para la autocomprobación interna de su código. Assert hace que la depuración sea realmente fácil cuando su código entra en casos extremos imposibles. Afirma verificar esos casos imposibles.
Digamos que hay una función para calcular el precio del artículo después del descuento:
aquí, precio_descontado nunca puede ser menor que 0 y mayor que el precio real. Por lo tanto, en caso de que se viole la condición anterior, la afirmación genera un Error de aserción, que ayuda al desarrollador a identificar que algo imposible ha sucedido.
Espero eso ayude :)
fuente
assert
es útil en un contexto de depuración, pero no debe confiarse fuera de un contexto de depuración.Mi breve explicación es:
assert
se elevaAssertionError
si la expresión es falsa, de lo contrario solo continúa el código, y si hay una coma sea lo que seaAssertionError: whatever after comma
, y codificar es como:raise AssertionError(whatever after comma)
Un tutorial relacionado sobre esto:
fuente
assert
, pero no cuándo usar (o no usar) unassert
; También señala que unassert
puede ser desactivado si__debug__
esFalse
útil.En Pycharm, si usa
assert
junto conisinstance
para declarar el tipo de un objeto, le permitirá acceder a los métodos y atributos del objeto principal mientras está codificando, se completará automáticamente.Por ejemplo, digamos que
self.object1.object2
es unMyClass
objeto.fuente
Como está escrito en otras respuestas, las
assert
declaraciones se utilizan para verificar el estado del programa en un punto dado.No repetiré lo que se dijo sobre el mensaje asociado, paréntesis u
-O
opción y__debug__
constante. Consulte también el documento para obtener información de primera mano. Me centraré en su pregunta: ¿de qué sirveassert
? Más precisamente, ¿cuándo (y cuándo no) se debe usarassert
?Las
assert
declaraciones son útiles para depurar un programa, pero se desaconseja verificar la entrada del usuario. Utilizo la siguiente regla general: mantener las aserciones para detectar una situación que no debería suceder . Una entrada del usuario puede ser incorrecta, por ejemplo, una contraseña demasiado corta, pero esto no es un caso que no debería ocurrir . Si el diámetro de un círculo no es dos veces mayor que su radio, está en un caso que no debería suceder .El uso más interesante, en mi opinión,
assert
está inspirado en la programación por contrato según lo descrito por B. Meyer en [Construcción de software orientada a objetos] ( https://www.eiffel.org/doc/eiffel/Object-Oriented_Software_Construction% 2C_2nd_Edition ) e implementado en el [lenguaje de programación Eiffel] ( https://en.wikipedia.org/wiki/Eiffel_(programming_language) ). No puede emular completamente la programación por contrato utilizando laassert
declaración, pero es interesante mantener la intención.Aquí hay un ejemplo. Imagine que tiene que escribir una
head
función (como la [head
función en Haskell] ( http://www.zvon.org/other/haskell/Outputprelude/head_f.html )). La especificación que se le da es: "si la lista no está vacía, devuelva el primer elemento de una lista". Mira las siguientes implementaciones:Y
(Sí, esto se puede escribir como
return xs[0] if xs else None
, pero ese no es el punto) .Si la lista no está vacía, ambas funciones tienen el mismo resultado y este resultado es correcto:
Por lo tanto, ambas implementaciones son (espero) correctas. Se diferencian cuando intenta tomar el elemento principal de una lista vacía:
Pero:
Nuevamente, ambas implementaciones son correctas, porque nadie debería pasar una lista vacía a estas funciones (estamos fuera de la especificación ). Esa es una llamada incorrecta, pero si hace una llamada así, puede pasar cualquier cosa. Una función genera una excepción, la otra devuelve un valor especial. Lo más importante es: no podemos confiar en este comportamiento . Si
xs
está vacío, esto funcionará:Pero esto bloqueará el programa:
Para evitar algunas sorpresas, me gustaría saber cuándo estoy pasando algún argumento inesperado a una función. En otras palabras: me gustaría saber cuándo el comportamiento observable no es confiable, porque depende de la implementación, no de la especificación. Por supuesto, puedo leer la especificación, pero los programadores no siempre leen con cuidado los documentos.
Imagínese si tuviera una forma de insertar la especificación en el código para obtener el siguiente efecto: cuando violo la especificación, por ejemplo, al pasar una lista vacía a
head
, recibo una advertencia. Sería de gran ayuda escribir un programa correcto (es decir, que cumpla con la especificación). Y ahí es dondeassert
entra en escena:Y
Ahora tenemos:
Y:
Tenga en cuenta que
head1
arroja unAssertionError
, no unIndexError
. Eso es importante porqueAssertionError
no es un error de tiempo de ejecución: indica una violación de la especificación. Quería una advertencia, pero recibo un error. Afortunadamente, puedo desactivar el cheque (usando la-O
opción), pero bajo mi propio riesgo. Lo haré, un choque es realmente costoso, y espero lo mejor. Imagine que mi programa está incrustado en una nave espacial que viaja a través de un agujero negro. Desactivaré las afirmaciones y espero que el programa sea lo suficientemente robusto como para no bloquearse el mayor tiempo posible.Este ejemplo fue solo sobre condiciones previas, ya que puede usarlas
assert
para verificar las condiciones posteriores (el valor de retorno y / o el estado) y las invariantes (estado de una clase). Tenga en cuenta que verificar las condiciones posteriores y las invariantes conassert
puede ser engorroso:No tendrá algo tan sofisticado como Eiffel, pero puede mejorar la calidad general de un programa.
Para resumir, la
assert
declaración es una forma conveniente de detectar una situación que no debería suceder . Las violaciones de la especificación (por ejemplo, pasar una lista vacía ahead
) son de primera clase, esto no debería suceder en situaciones. Por lo tanto, aunque laassert
declaración se puede usar para detectar cualquier situación inesperada, es una forma privilegiada de garantizar que se cumpla la especificación. Una vez que haya insertadoassert
declaraciones en el código para representar la especificación, podemos esperar que haya mejorado la calidad del programa porque se informarán argumentos incorrectos, valores de retorno incorrectos, estados incorrectos de una clase ...fuente
formato: afirmar Expresión [, argumentos] Cuando afirmar encuentra una declaración, Python evalúa la expresión. Si la declaración no es verdadera, se genera una excepción (aserciónError). Si la aserción falla, Python usa ArgumentExpression como argumento para AssertionError. Las excepciones AssertionError pueden detectarse y manejarse como cualquier otra excepción utilizando la instrucción try-except, pero si no se manejan, terminarán el programa y producirán un rastreo. Ejemplo:
Cuando se ejecuta el código anterior, produce el siguiente resultado:
fuente
Se puede usar para garantizar que los parámetros se pasen en la llamada de función.
fuente
if not user_key: raise ValueError()
últimos 2 párrafos de verificación aquí: wiki.python.org/moin/UsingAssertionsEffectivelyassert
no debe usarse para la validación de entrada porque la validación se eliminará si__debug__
es asíFalse
. Además, el uso de aserciones para fines que no sean de depuración puede hacer que las personas capturen los correosAssertionError
electrónicos resultantes , lo que puede hacer que la depuración sea más difícil en lugar de menos.fuente
Básicamente, el significado de la palabra clave afirmar es que si la condición no es verdadera, entonces a través de un error de aserción, de lo contrario, continuará, por ejemplo, en Python.
código-1
SALIDA:
código-2
SALIDA:
fuente
assert
, pero no responde cuándo usar (o no usar) unassert
.