2015-07-15 13 views
6

Ho una riga di codice nel mio script che ha entrambi questi operatori concatenati. Dalla documentazione di riferimento BOOLEAN E ha precedenza inferiore rispetto a COMPARAZIONE DI MAGGIORANZA DI. Sto ottenendo risultati inattesi qui, in questo codice:Precisione dell'operatore Python - e superiore a

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

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

mi aspettavo Seconda o Terza prova per accadere prima che il pugno, dal momento > operatore ha una precedenza più alta. Cosa sto facendo di sbagliato qui?

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

+2

L'interpretazione booleana del tuo primo valore, '10', è anche True. Pertanto, '10 e 15> 5 == 10 e (15> 5) == 10 e True == True' – Finwood

+0

Ma perché l'interprete ha ottenuto 10 prima di 15 o 5? Il confronto non dovrebbe avvenire prima dei controlli booleani? –

+0

'test (" First ", 10) e test (" Second ", 15)> test (" Third ", 5)' è equivalente a 'test (" First ", 10) e (test (" Second ", 15)> test ("Terzo", 5)) 'Anche Python valuta' and' [pigramente] (https://docs.python.org/3/reference/expressions.html#boolean-operations) – Alik

risposta

7

Perché si sta guardando la cosa sbagliata. call (o chiamata di funzione) prende la precedenza più alta sia su and sia su > (maggiore di). Quindi le prime chiamate di funzione avvengono da sinistra a destra.

Python otterrà i risultati per tutte le chiamate di funzione prima che avvenga il confronto. L'unica cosa che prevale qui è il cortocircuito, quindi se test("First",10) restituisce False, si interrompe e restituisce False.

I confronti e and si verificano ancora nella stessa precendenza, cioè prima il risultato di test("Second", 15) viene confrontato con test("Third", 5) (si prega di notare solo i valori di ritorno (la chiamata di funzione già accaduto prima)). Quindi il risultato di test("Second", 15) > test("Third", 5) viene utilizzato nell'operazione and.

Dalla documentazione sulla operator precedence -

enter image description here

+0

Questo ha perfettamente senso. Grazie. Quindi, se sostituisco le chiamate di funzione con solo numeri, otterrò un risultato diverso, giusto? –

+0

Per i numeri non c'è nulla da valutare, quindi non sono sicuro di cosa intendi con questo? –

+0

Python otterrà i risultati per tutte le chiamate di funzione prima che avvenga il confronto o "e" accade. L'unica cosa che prende la precedenza qui sarebbe un cortocircuito –

3

Un modo per vedere cosa sta succedendo è guardare esattamente come Python interpreta questo risultato:

>>> 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   

Se fate lo stesso per 10 and 15 > 5, ottieni:

>>> 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