Unterstützt Python Kurzschlüsse?

Antworten:

304

Ja, beide andund der orBediener schließen kurz - siehe die Dokumente .

Alex Martelli
quelle
192

Kurzschlussverhalten im Bediener and, or:

Definieren wir zunächst eine nützliche Funktion, um festzustellen, ob etwas ausgeführt wird oder nicht. Eine einfache Funktion, die ein Argument akzeptiert, eine Nachricht druckt und die Eingabe unverändert zurückgibt.

>>> def fun(i):
...     print "executed"
...     return i
... 

Man kann das beobachten Pythons Kurzschlussverhalten von and, orOperatoren im folgende Beispiel:

>>> fun(1)
executed
1
>>> 1 or fun(1)    # due to short-circuiting  "executed" not printed
1
>>> 1 and fun(1)   # fun(1) called and "executed" printed 
executed
1
>>> 0 and fun(1)   # due to short-circuiting  "executed" not printed 
0

Hinweis: Die folgenden Werte werden vom Interpreter als falsch angesehen:

        False    None    0    ""    ()    []     {}

Kurzschlussverhalten in Funktion: any(), all():

Pythons any()und all()Funktionen unterstützen auch das Kurzschließen. Wie in den Dokumenten gezeigt; Sie bewerten jedes Element einer Sequenz der Reihe nach, bis sie ein Ergebnis finden, das einen frühen Ausstieg aus der Bewertung ermöglicht. Betrachten Sie die folgenden Beispiele, um beide zu verstehen.

Die Funktion any()prüft, ob ein Element True ist. Die Ausführung wird beendet, sobald ein True gefunden wird, und True zurückgegeben.

>>> any(fun(i) for i in [1, 2, 3, 4])   # bool(1) = True
executed
True
>>> any(fun(i) for i in [0, 2, 3, 4])   
executed                               # bool(0) = False
executed                               # bool(2) = True
True
>>> any(fun(i) for i in [0, 0, 3, 4])
executed
executed
executed
True

Die Funktion all()überprüft, ob alle Elemente wahr sind, und beendet die Ausführung, sobald ein falsches Ergebnis auftritt:

>>> all(fun(i) for i in [0, 0, 3, 4])
executed
False
>>> all(fun(i) for i in [1, 0, 3, 4])
executed
executed
False

Kurzschlussverhalten im verketteten Vergleich:

Zusätzlich in Python

Vergleiche können beliebig verkettet werden ; Dies ist beispielsweise x < y <= zäquivalent zu x < y and y <= z, außer dass dies ynur einmal ausgewertet wird (in beiden Fällen zjedoch überhaupt nicht, wenn x < ysich herausstellt, dass es falsch ist).

>>> 5 > 6 > fun(3)    # same as:  5 > 6 and 6 > fun(3)
False                 # 5 > 6 is False so fun() not called and "executed" NOT printed
>>> 5 < 6 > fun(3)    # 5 < 6 is True 
executed              # fun(3) called and "executed" printed
True
>>> 4 <= 6 > fun(7)   # 4 <= 6 is True  
executed              # fun(3) called and "executed" printed
False
>>> 5 < fun(6) < 3    # only prints "executed" once
executed
False
>>> 5 < fun(6) and fun(6) < 3 # prints "executed" twice, because the second part executes it again
executed
executed
False

Edit:
Ein interessanter Punkt ist zu beachten : - Logisch and,or Operatoren in Python Gibt einen Operandenwert anstelle einem Boolean ( Trueoder False). Zum Beispiel:

Operation x and ygibt das Ergebnisif x is false, then x, else y

Anders als in anderen Sprachen , zB &&, ||Operatoren in C , dass Rückkehr entweder 0 oder 1.

Beispiele:

>>> 3 and 5    # Second operand evaluated and returned 
5                   
>>> 3  and ()
()
>>> () and 5   # Second operand NOT evaluated as first operand () is  false
()             # so first operand returned 

In ähnlicher Weise gibt der orOperator den am weitesten links liegenden Wert zurück, für den bool(value)== Truesonst der am weitesten rechts liegende falsche Wert (je nach Kurzschlussverhalten), Beispiele:

>>> 2 or 5    # left most operand bool(2) == True
2    
>>> 0 or 5    # bool(0) == False and bool(5) == True
5
>>> 0 or ()
()

Wie ist das nützlich? Ein Beispiel für die Verwendung in Practical Python von Magnus Lie Hetland:
Angenommen, ein Benutzer soll seinen Namen eingeben, kann jedoch nichts eingeben. In diesem Fall möchten Sie den Standardwert verwenden '<unknown>'. Sie könnten eine if-Anweisung verwenden, aber Sie könnten die Dinge auch sehr prägnant formulieren:

In [171]: name = raw_input('Enter Name: ') or '<Unkown>'
Enter Name: 

In [172]: name
Out[172]: '<Unkown>'

Mit anderen Worten, wenn der Rückgabewert von raw_input true ist (keine leere Zeichenfolge), wird er dem Namen zugewiesen (nichts ändert sich). Andernfalls wird der Standardwert '<unknown>'zugewiesen name.

Grijesh Chauhan
quelle
1
Kleiner Streit: Die explizite Liste der falschen Werte ist leicht irreführend. Jeder Typ kann einen oder mehrere falsche Werte haben. Vereinbarungsgemäß werden alle numerischen Typen mit Wert 0sind falsy (so ist es nicht nur 0, es ist 0.0, 0j, decimal.Decimal(0), fractions.Fraction(0), etc.), da alle Sammlungen mit Länge sind 0(so auf, was Sie aufgelistet, b''[PY3], u''[Py2] und set()/ frozenset()sind Alle integrierten Funktionen, die als falsch ausgewertet werden, aber benutzerdefinierte Typen / Typen von Drittanbietern können ihre eigenen definieren (mit __bool__[Py3] / __nonzero__[Py2] direkt oder indirekt durch Definieren __len__).
ShadowRanger
@ShadowRanger hier wird dein Kommentar meine Antwort vervollständigen. Vielen Dank für das Hinzufügen dieser Notiz.
Grijesh Chauhan
Außerdem wertet Python kurzgeschlossene Bedingungen doppelt aus, wenn sie später als Boolesche Werte verwendet werden ... es sei denn, sie befinden sich in einer privilegierten if-Anweisung: gist.github.com/earonesty/08e9cbe083a5e0583feb8a34cc538010
Erik Aronesty
48

Ja. Versuchen Sie Folgendes in Ihrem Python-Interpreter:

und

>>>False and 3/0
False
>>>True and 3/0
ZeroDivisionError: integer division or modulo by zero

oder

>>>True or 3/0
True
>>>False or 3/0
ZeroDivisionError: integer division or modulo by zero
Caprooja
quelle