2011-01-19 17 views
11

Ho una semplice domanda riguardante l'uso delle parentesi nelle istruzioni condizionali Python.parentesi in condizionali Python

I seguenti due frammenti funzionano ugualmente ma mi chiedo se questo è vero solo per la sua semplicità;

>>> import os, socket 
>>> if ((socket.gethostname() == "bristle") or (socket.gethostname() == "rete")): 
...  DEBUG = False 
... else: 
...  DEBUG = True 
... 
>>> DEBUG 

e ora senza parentesi

>>> import os, socket 
>>> if socket.gethostname() == "bristle" or socket.gethostname() == "rete": 
...  DEBUG = False 
... else: 
...  DEBUG = True 
... 
>>> DEBUG 

Qualcuno potrebbe aiutare a far luce su questo? Sono i loro casi in cui dovrei sicuramente usarli?

risposta

32

Le altre risposte che il confronto si svolge prima booleano sono corrette al 100%. In alternativa (per situazioni come quello che hai dimostrato) è anche possibile utilizzare questo come un modo per combinare le condizioni:

if socket.gethostname() in ('bristle', 'rete'): 
    # Something here that operates under the conditions. 

che ti salva le chiamate separate per socket.gethostname e rende più facile per aggiungere ulteriori possibili valori validi man mano che il progetto cresce o devi autorizzare host aggiuntivi.

8

In questo caso le parentesi sono ridondanti. Il confronto ha una precedenza più alta rispetto agli operatori booleani, quindi i confronti verranno sempre eseguiti per primi indipendentemente dalle parentesi.

Detto questo, una linea guida, una volta che ho visto (forse in Practical C Programming) detto qualcosa di simile:

  1. moltiplicazione e divisione prima
  2. Addizione e sottrazione successiva
  3. parentesi attorno tutto il resto

(Sì, IIRC hanno lasciato fuori elevamento a potenza!)

L'idea è che le regole di precedenza sono abbastanza arcane che nessuno dovrebbe aspettarsi di ricordarle tutte, né il programmatore originale né il programmatore di manutenzione leggono il codice, quindi è meglio renderlo esplicito. Essenzialmente le parentesi servono sia a comunicare l'intento al compilatore sia come documentazione per il prossimo schmoe che deve lavorarci sopra.

Credo in Python che queste due istruzioni genereranno lo stesso bytecode in modo da non perdere nemmeno l'efficienza.

+0

La precedenza dell'operatore di C è strana. Python non lo è. Quindi in Python i parenti non sono altrettanto spesso garantiti come in C. – delnan

+2

Ma c'è anche l'idioma python "esplicita è meglio di implicita". Se c'è una possibilità di confusione, attaccali dentro. – Wilduck

+2

Sì, C è molto più strano di Python. Tuttavia, cercare di tenerli in linea con le varie lingue che si usano può essere fonte di confusione in sé. – kindall

5

La parentesi forza solo un ordine di operazioni. Se hai avuto una parte aggiuntiva nel tuo condizionale, come un 'e', ​​sarebbe consigliabile usare le parentesi per indicare quale 'o' che 'e' abbinato a.

if (socket.gethostname() == "bristle" or socket.gethostname() == "rete") and var == condition: 
    ... 

da differenziare da

if socket.gethostname() == "bristle" or (socket.gethostname() == "rete" and var == condition): 
    ... 
2

In Python e in molti altri linguaggi di programmazione, non sono richieste parentesi per ogni espressione con più operatori. Questo perché gli operatori hanno una precedenza definita. Vedi la tabella here (Sezione 5.15) per informazioni sulla precedenza degli operatori in Python.

È possibile tracciare un'analogia con l'aritmetica.Queste espressioni sono equivalenti:

5 * 5 + 3 

(5 * 5) + 3 

Se intendi aggiungere tre primi, allora avete bisogno di usare le parentesi in questo modo:

5 * (5 + 3) 
0

Dai un'occhiata alla the manual. Più in alto sei nella lista, l'operatore verrà applicato più tardi. "or" is above "==", e quindi, in questo caso particolare le risposte sono le stesse. Tuttavia, per la leggibilità, e per sicurezza, raccomando una parentesi.