python affirmer avec et sans parenthèse

Voici quatre invocations simples d’affirmation:

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

Notez que le dernier ne génère pas d’erreur. Quelle est la différence entre appeler assert avec ou sans parenthèse qui provoque ce comportement? Ma pratique est d’utiliser des parenthèses, mais ce qui précède suggère que je ne devrais pas.

La dernière SyntaxWarning: assertion is always true, perhaps remove parentheses? vous aurait donné un avertissement ( SyntaxWarning: assertion is always true, perhaps remove parentheses? ) Si vous l’avez exécutée via un interpréteur complet, pas via IDLE. Dans la mesure où assert est un mot-clé et non une fonction, vous passez en fait un tuple en tant que premier argument et en ignorant le second argument.

Rappelez-vous que les n-uplets non vides sont évalués à True et que le message d’assertion est facultatif, vous avez essentiellement appelé assert True lorsque vous avez écrit assert(1==2, "hi") .

assert 1==2, "hi" est analysé comme assert 1==2, "hi" avec “hi” comme second paramètre du mot-clé. D’où pourquoi il donne correctement une erreur.

assert(1==2) est analysé comme assert (1==2) ce qui est identique pour assert 1==2 , car parens autour d’un seul élément ne crée pas de tuple à moins qu’il y ait une virgule finale (1==2,) .

assert(1==2, "hi") est analysé comme assert (1==2, "hi") , ce qui ne donne pas d’erreur car un tuple non vide (False, "hi") n’est pas un valeur fausse, et il n’y a pas de second paramètre fourni au mot clé.

Vous ne devriez pas utiliser de parenthèses car assert n’est pas une fonction dans Python – c’est un mot clé.

Si vous placez la parenthèse parce que vous vouliez une assertion sur plusieurs lignes, une alternative consiste à placer une barre oblique inverse à la fin de la ligne, comme ceci:

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

Impressions:

 AssertionError: "derp should be 8, it is 7 

Pourquoi ce python doit-il être différent de tout le rest:

Je pense que l’idéologie pythonique est qu’un programme devrait s’auto-corriger sans avoir à se soucier du drapeau spécial pour activer les assertions. La tentation d’éteindre les assertions est trop grande et elle est donc déconseillée.

Je partage votre désagrément que l’assertion de python ait une syntaxe unique par rapport à toutes les autres constructions de programmation python, et cette syntaxe a encore changé de python2 à python3, rendant les déclarations d’assertivité non compatibles.

C’est un coup sur l’épaule qui est un citoyen de 3ème classe, il sera totalement supprimé dans python4, et certainement encore dans Python 8.1.

Vous pouvez casser l’assertion sans \ comme ceci:

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

Ou si vous avez un message encore plus long:

 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' ) 

Ce qui suit est cité dans le doc python

Les instructions d’assertion permettent d’insérer des assertions de débogage dans un programme:

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

La forme simple, assert expression, est équivalente à if __debug__: if not expression: raise AssertionError

La forme étendue, assert expression1, expression2 , est équivalente à if __debug__: if not expression1: raise AssertionError(expression2)

Donc, lorsque vous utilisez des parenthèses ici, vous utilisez la forme simple, et l’expression est évaluée comme un tuple, qui est toujours vrai lors de la conversion en booléen.