Voici quatre invocations simples d'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")
Notez que le dernier ne soulève pas d'erreur. Quelle est la différence entre l'appel à assert avec ou sans parenthèse qui provoque ce comportement? Ma pratique consiste à utiliser des parenthèses, mais ce qui précède suggère que je ne devrais pas.
python
assert
parentheses
gaefan
la source
la source
Réponses:
Le dernier vous
assert
aurait donné un avertissement (SyntaxWarning: assertion is always true, perhaps remove parentheses?
) si vous l'aviez exécuté via un interpréteur complet, et non via IDLE. Comme ilassert
s'agit d'un mot-clé et non d'une fonction, vous passez en fait un tuple comme premier argument et laissez le second argument.Rappelez-vous que les tuples non vides évaluent à
True
, et comme le message d'assertion est facultatif, vous l'avez essentiellement appeléassert True
lorsque vous avez écritassert(1==2, "hi")
.la source
assert (1==2)
parenthèses autour d'une seule expression ne créent pas automatiquement un tuple; vous auriez le même comportement que le n ° 4 si vous le faisiezassert (1==2,)
. La même chose se produirait si vous faisiez à laprint ('foo', 'bar')
place deprint 'foo', 'bar'
; vous verriez le tuple sortiassert(test, message)
probablement erronées et certainement déroutantes. Pas de parent!Si vous mettez la parenthèse là-dedans parce que vous vouliez une assertion multiligne, alors une alternative est de mettre une barre oblique inverse à la fin de la ligne comme ceci:
Impressions:
Pourquoi ce python
assert
doit-il être différent de tout le reste:Je pense que l'idéologie pythonique est qu'un programme doit s'auto-corriger sans avoir à se soucier du drapeau spécial pour activer les affirmations. La tentation de désactiver les assertions est trop grande et est donc obsolète.
Je partage votre mécontentement que le python
assert
a une syntaxe unique par rapport à toutes les autres constructions de programmation python, et cette syntaxe a encore une fois changé de python2 à python3 et à nouveau changé de python 3.4 à 3.6. Rendre les instructions assert non rétrocompatibles d'une version à une autre.C'est une tape sur l'épaule qui
assert
est un citoyen de 3ème classe, il sera totalement supprimé en python4, et certainement à nouveau en Python 8.1.la source
assert 1==2, "hi"
est analysé commeassert 1==2, "hi"
avec "hi" comme deuxième paramètre du mot-clé. D'où pourquoi il donne correctement une erreur.assert(1==2)
est analysé commeassert (1==2)
étant identique àassert 1==2
, car les parenthèses autour d'un seul élément ne créent pas de tuple à moins qu'il n'y ait une virgule à la fin, par exemple(1==2,)
.assert(1==2, "hi")
est analysé commeassert (1==2, "hi")
, ce qui ne donne pas d'erreur car un tuple non vide(False, "hi")
n'est pas une valeur fausse et il n'y a pas de deuxième paramètre fourni au mot clé.Vous ne devriez pas utiliser de parenthèses car ce
assert
n'est pas une fonction en Python - c'est un mot-clé.la source
Vous pouvez casser l'instruction assert sans
\
comme ceci:Ou si vous avez un message encore plus long:
la source
Ce qui suit est cité dans la documentation python
La forme simple, assert expression, équivaut à
if __debug__: if not expression: raise AssertionError
La forme étendue, assert expression1, expression2 , équivaut à
if __debug__: if not expression1: raise AssertionError(expression2)
Ainsi, lorsque vous utilisez des parenthèses ici, vous utilisez le formulaire simple et l'expression est évaluée comme un tuple, ce qui est toujours True lors du cast en bool.
la source