Dans de nombreux cas, Python ressemble et se comporte comme un anglais naturel, mais c'est un cas où cette abstraction échoue. Les gens peuvent utiliser des indices de contexte pour déterminer que «Jon» et «Inbar» sont des objets joints au verbe «égal», mais l'interpréteur Python est plus littéral.
if name == "Kevin" or "Jon" or "Inbar":
équivaut logiquement à:
if (name == "Kevin") or ("Jon") or ("Inbar"):
Ce qui, pour l'utilisateur Bob, équivaut à:
if (False) or ("Jon") or ("Inbar"):
L' oropérateur choisit le premier argument avec une valeur de vérité positive :
if ("Jon"):
Et comme "Jon" a une valeur de vérité positive, le ifbloc s'exécute. C'est ce qui provoque l'impression de "Accès accordé" quel que soit le nom donné.
Tout ce raisonnement s'applique également à l'expression if "Kevin" or "Jon" or "Inbar" == name . la première valeur "Kevin",, est vraie, donc le ifbloc s'exécute.
Il existe deux façons courantes de construire correctement ce conditionnel.
Utilisez plusieurs ==opérateurs pour vérifier explicitement chaque valeur:
if name == "Kevin" or name == "Jon" or name == "Inbar":
Composez une séquence de valeurs valides et utilisez l' inopérateur pour tester l'appartenance:
if name in {"Kevin", "Jon", "Inbar"}:
En général, le second devrait être préféré car il est plus facile à lire et aussi plus rapide:
>>> import timeit
>>> timeit.timeit('name == "Kevin" or name == "Jon" or name == "Inbar"', setup="name='Inbar'")
0.4247764749999945
>>> timeit.timeit('name in {"Kevin", "Jon", "Inbar"}', setup="name='Inbar'")
0.18493307199999265
Pour ceux qui veulent une preuve qui if a == b or c or d or e: ...est en effet analysée comme ça. Le astmodule intégré fournit une réponse:
>>> import ast
>>> ast.parse("if a == b or c or d or e: ...")
<_ast.Module object at 0x1031ae6a0>
>>> ast.dump(_)
"Module(body=[If(test=BoolOp(op=Or(), values=[Compare(left=Name(id='a', ctx=Load()), ops=[Eq()], comparators=[Name(id='b', ctx=Load())]), Name(id='c', ctx=Load()), Name(id='d', ctx=Load()), Name(id='e', ctx=Load())]), body=[Expr(value=Ellipsis())], orelse=[])])"
>>>
Ainsi , le testdes ifétats se présente comme suit:
BoolOp(
op=Or(),
values=[
Compare(
left=Name(id='a', ctx=Load()),
ops=[Eq()],
comparators=[Name(id='b', ctx=Load())]
),
Name(id='c', ctx=Load()),
Name(id='d', ctx=Load()),
Name(id='e', ctx=Load())
]
)
Comme on peut le voir, il est l'opérateur booléen orappliqué à plusieurs values, à savoir, a == bet c, det e.