In vielen Fällen sieht Python wie natürliches Englisch aus und verhält sich auch so. In diesem Fall schlägt diese Abstraktion jedoch fehl. Menschen können Kontexthinweise verwenden, um festzustellen, dass "Jon" und "Inbar" Objekte sind, die mit dem Verb "gleich" verbunden sind, aber der Python-Interpreter ist wörtlicher.
if name == "Kevin" or "Jon" or "Inbar":
ist logisch äquivalent zu:
if (name == "Kevin") or ("Jon") or ("Inbar"):
Was für Benutzer Bob gleichbedeutend ist mit:
if (False) or ("Jon") or ("Inbar"):
Der orOperator wählt das erste Argument mit einem positiven Wahrheitswert :
if ("Jon"):
Und da "Jon" einen positiven Wahrheitswert hat, wird der ifBlock ausgeführt. Aus diesem Grund wird "Zugriff gewährt" unabhängig vom angegebenen Namen gedruckt.
All diese Überlegungen gelten auch für den Ausdruck if "Kevin" or "Jon" or "Inbar" == name. Der erste Wert "Kevin"ist true, daher wird der ifBlock ausgeführt.
Es gibt zwei übliche Möglichkeiten, diese Bedingung richtig zu konstruieren.
Verwenden Sie mehrere ==Operatoren, um explizit mit jedem Wert zu vergleichen:
if name == "Kevin" or name == "Jon" or name == "Inbar":
Erstellen Sie eine Folge gültiger Werte und intesten Sie mit dem Operator die Mitgliedschaft:
if name in {"Kevin", "Jon", "Inbar"}:
Im Allgemeinen sollte die zweite bevorzugt werden, da sie leichter zu lesen und auch schneller ist:
>>> 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
Für diejenigen, die Beweise wollen, if a == b or c or d or e: ...die tatsächlich so analysiert werden. Das eingebaute astModul bietet eine Antwort:
>>> 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=[])])"
>>>
So ist die testder ifAussage sieht wie folgt aus :
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())
]
)
Wie man sehen kann, ist es der Booleschen Operator orauf mehr angewandt values, nämlich a == bund c, dund e.