2015-07-15 10 views
6

Ich habe eine Codezeile in meinem Skript, das diese beiden Operatoren miteinander verkettet hat. Aus der Dokumentationsreferenz hat BOOLEAN UND eine niedrigere Priorität als . VERGLEICH MEHR ALS. Ich erhalte unerwartete Ergebnisse hier in diesem Code:Python-Operator Vorrang - und vs größer als

>>> def test(msg, value): 
...  print(msg) 
...  return value 

>>> test("First", 10) and test("Second", 15) > test("Third", 5) 
First 
Second 
Third 
True 

Ich erwarte zweiter oder dritter Test geschehen, bevor die Faust ein, da > Operator eine höhere Priorität hat. Was mache ich hier falsch?

https://docs.python.org/3/reference/expressions.html#operator-precedence

+2

Die boolesche Interpretation Ihres ersten Werts "10" ist ebenfalls True. Deshalb, 10 und 15> 5 == 10 und (15> 5) == 10 und Wahr == Wahr ' – Finwood

+0

Aber warum hat der Dolmetscher 10 bekommen, bevor es 15 oder 5 getan hat? Sollte der Vergleich nicht vor booleschen Überprüfungen stattfinden? –

+0

'Test (" First ", 10) und Test (" Second ", 15)> Test (" Third ", 5)' ist gleichbedeutend mit 'test (" First ", 10) und (test (" Second ", 15)> test ("Third", 5)) 'Auch Python wertet' und '[lazily] aus (https://docs.python.org/3/reference/expressions.html#boolean-operatings) – Alik

Antwort

7

Weil du an der falschen Sache suchen. call (oder Funktionsaufruf) hat einen höheren Vorrang gegenüber and sowie > (größer als). Die ersten Funktionsaufrufe erfolgen also von links nach rechts.

Python wird die Ergebnisse für alle Funktionsaufrufe erhalten, bevor beide Vergleiche stattfinden. Das einzige, was hier Vorrang hat, wäre ein Kurzschluss. Wenn also test("First",10) False zurückgegeben wird, würde es einen Kurzschluss verursachen und False zurückgeben.

Die Vergleiche und and treten nach wie vor in der gleichen precendence, dass zuerst das Ergebnis der test("Second", 15) ist verglichen gegen test("Third", 5) (bitte nur die Rückgabewerte beachten (der Funktionsaufruf vor bereits aufgetreten)). Dann wird das Ergebnis von test("Second", 15) > test("Third", 5) im and-Betrieb verwendet.

Aus der Dokumentation auf operator precedence -

enter image description here

+0

Das macht vollkommen Sinn. Vielen Dank. Also, wenn ich Funktionsaufrufe durch nur Zahlen ersetze, bekomme ich ein anderes Ergebnis, oder? –

+0

Für Zahlen gibt es nichts zu bewerten, also bin ich mir nicht sicher, was Sie damit meinen? –

+0

Python wird die Ergebnisse für alle Funktionsaufrufe erhalten, bevor ein Vergleich stattfindet oder "und" passiert. Das einzige, was hier Vorrang hat, wäre ein Kurzschluss –

3

Ein Weg, um zu sehen, was passiert, ist genau zu prüfen, wie Python dieses Ergebnis interpretiert:

>>> x = lambda: test("First", 10) and test("Second", 15) > test("Third", 5) 
>>> dis.dis(x) 
    1   0 LOAD_GLOBAL    0 (test) 
       3 LOAD_CONST    1 ('First') 
       6 LOAD_CONST    2 (10) 
       9 CALL_FUNCTION   2 
      12 JUMP_IF_FALSE_OR_POP 42 
      15 LOAD_GLOBAL    0 (test) 
      18 LOAD_CONST    3 ('Second') 
      21 LOAD_CONST    4 (15) 
      24 CALL_FUNCTION   2 
      27 LOAD_GLOBAL    0 (test) 
      30 LOAD_CONST    5 ('Third') 
      33 LOAD_CONST    6 (5) 
      36 CALL_FUNCTION   2 
      39 COMPARE_OP    4 (>) 
     >> 42 RETURN_VALUE   

Wenn Sie das gleiche tun für 10 and 15 > 5, erhalten Sie:

>>> x = lambda: 10 and 15 > 5 
>>> dis.dis(x) 
    1   0 LOAD_CONST    1 (10) 
       3 JUMP_IF_FALSE_OR_POP 15 
       6 LOAD_CONST    2 (15) 
       9 LOAD_CONST    3 (5) 
      12 COMPARE_OP    4 (>) 
     >> 15 RETURN_VALUE