Pregunta pitón afirma con y sin paréntesis


Aquí hay cuatro simples invocaciones de assert:

>>> assert 1==2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError

>>> assert 1==2, "hi"
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError: hi

>>> assert(1==2)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError

>>> assert(1==2, "hi")

Tenga en cuenta que el último no genera un error. ¿Cuál es la diferencia entre llamar afirmar con o sin paréntesis que causa este comportamiento? Mi práctica es usar paréntesis, pero lo anterior sugiere que no debería.


72
2018-06-24 16:59


origen


Respuestas:


El último assert Te habría dado una advertencia (SyntaxWarning: assertion is always true, perhaps remove parentheses?) si lo ejecutó a través de un intérprete completo, no a través de IDLE. Porque assert es una palabra clave y no una función, en realidad está pasando una tupla como primer argumento y dejando fuera el segundo argumento.

Recuerde que las tuplas no vacías se evalúan como True, y dado que el mensaje de aserción es opcional, esencialmente ha llamado assert True cuando escribiste assert(1==2, "hi").


85
2018-06-24 17:00



assert 1==2, "hi" es analizado como assert 1==2, "hi" con "hola" como el segundo parámetro para la palabra clave. Por lo tanto, por qué da correctamente un error.

assert(1==2) es analizado como assert (1==2) que es idéntico a assert 1==2, porque los parens alrededor de un solo elemento no crean una tupla a menos que haya una coma final, p. (1==2,).

assert(1==2, "hi") es analizado como assert (1==2, "hi"), que no da un error porque una tupla no vacía (False, "hi") no es un valor falso, y no hay un segundo parámetro proporcionado a la palabra clave.

No deberías usar paréntesis porque assert no es una función en Python, es una palabra clave.


12
2018-06-24 17:03



Si coloca el paréntesis allí porque quería una afirmación de varias líneas, entonces una alternativa es poner una barra invertida al final de la línea como esta:

foo = 7
assert foo == 8, \
    "derp should be 8, it is " + str(foo)

Huellas dactilares:

AssertionError: "derp should be 8, it is 7

¿Por qué esta pitón assert tiene que ser diferente de todo lo demás:

Creo que la ideología pitonica es que un programa debería autocorregirse sin tener que preocuparse por la bandera especial para activar aseveraciones. La tentación de desactivar las afirmaciones es demasiado grande y, por lo tanto, está en desuso.

Comparto tu molestia de que la pitón assert tiene una sintaxis única relativa a todas las demás construcciones de programación de python, y esta sintaxis ha cambiado nuevamente de python2 a python3, lo que hace que las afirmaciones de afirmación no sean retrocompatibles.

Es un toque en el hombro que assert es un ciudadano de tercera clase, se eliminará por completo en python4, y ciertamente nuevamente en Python 8.1.


12
2017-07-07 15:16



Puede romper declaración de afirmación sin \ Me gusta esto:

foo = 7
assert foo == 8, (
    'derp should be 8, it is ' + str(foo))

O si tienes un mensaje aún más largo:

foo = 7
assert foo == 8, (
    'Lorem Ipsum is simply dummy text of the printing and typesetting '
    'industry. Lorem Ipsum has been the industry\'s standard dummy text '
    'ever since the 1500s'
)

2
2018-02-15 07:27



A continuación se cita de la python doc

Las declaraciones de confirmación son una forma conveniente de insertar las aserciones de depuración en un programa:

assert_stmt ::= "assert" expression ["," expression] 

La forma simple, expresión afirmativa, es equivalente a if __debug__: if not expression: raise AssertionError

La forma extendida, assert expression1, expression2, es equivalente a if __debug__: if not expression1: raise AssertionError(expression2)

Entonces, cuando usa paréntesis aquí, está usando la forma simple, y la expresión se evalúa como una tupla, que siempre es verdadera cuando se la envía a bool


0
2017-12-28 06:44