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 or
Operator wählt das erste Argument mit einem positiven Wahrheitswert :
if ("Jon"):
Und da "Jon" einen positiven Wahrheitswert hat, wird der if
Block 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 if
Block 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 in
testen 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 ast
Modul 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 test
der if
Aussage 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 or
auf mehr angewandt values
, nämlich a == b
und c
, d
und e
.