2010-10-19 10 views

risposta

632
if val is not None: 
    # ... 

è il linguaggio Pythonic per verificare che una variabile non è impostata None. Questo idioma ha usi particolari nel caso di declaring keyword functions with default parameters. is verifica l'identità in Python. Poiché esiste una sola istanza di None presente in uno script/programma Python in esecuzione, is è il test ottimale per questo. Come Johnsyweb points out, questo è discusso in PEP 8 in "Raccomandazioni di programmazione".

Per quanto riguarda il motivo per cui questo si preferisce

if not (val is None): 
    # ... 

questo è semplicemente parte del Zen of Python: "conta leggibilità". Good Python è spesso vicino al bene pseudocode.

+38

inoltre, "is not" ha una speciale semeantics creata per questo scopo (non è una conseguenza logica di come vengono costruite le espressioni: "1 is (not None)" e "1 is not None" hanno due esiti diversi: –

+13

+1: Mi è piaciuto questo riferimento - "Good Python è spesso vicino a un buon pseudocodice" – legesh

+1

"not None" restituisce True. Interessante. – Ries

18

Uno dei due ultimi, dal momento che val potrebbe potenzialmente essere di un tipo che definisce __eq__() per restituire true quando passato None.

+4

Questo è piuttosto vile '__eq __()' comportamento, e qualcosa che non avevo considerato. Buona risposta per aver catturato un caso d'angolo. – gotgenes

74

Da, Raccomandazioni di programmazione, PEP 8:

I paragoni con single come nessuno dovrebbe essere sempre fatto con 'è' o 'non è', mai gli operatori di uguaglianza.

Inoltre, fare attenzione a scrivere "se x" quando si intende realmente "se x non è None" - ad es. quando si verifica se una variabile o argomento che ha valore predefinito su Nessuno è stato impostato su un altro valore. L'altro valore potrebbe avere un tipo (come un contenitore) che potrebbe essere falso in un contesto booleano!

PEP 8 è una lettura essenziale per qualsiasi programmatore Python.

+4

+1 per la "lettura essenziale" - non lo sapevo – user2314737

12

La migliore scommessa con questo tipo di domande è vedere esattamente cosa fa Python. Il modulo dis è incredibilmente informativo:

>>> def f(val): 
... if val != None: 
...  return True 
... return False 
... 
>>> def g(val): 
... if not (val is None): 
...  return True 
... return False 
... 
>>> def h(val): 
... if val is not None: 
...  return True 
... return False 
... 
>>> import dis 
>>> dis.dis(f) 
    2   0 LOAD_FAST    0 (val) 
       3 LOAD_CONST    0 (None) 
       6 COMPARE_OP    3 (!=) 
       9 POP_JUMP_IF_FALSE  16 

    3   12 LOAD_GLOBAL    1 (True) 
      15 RETURN_VALUE 

    4  >> 16 LOAD_GLOBAL    2 (False) 
      19 RETURN_VALUE 
>>> dis.dis(g) 
    2   0 LOAD_FAST    0 (val) 
       3 LOAD_CONST    0 (None) 
       6 COMPARE_OP    9 (is not) 
       9 POP_JUMP_IF_FALSE  16 

    3   12 LOAD_GLOBAL    1 (True) 
      15 RETURN_VALUE 

    4  >> 16 LOAD_GLOBAL    2 (False) 
      19 RETURN_VALUE 
>>> dis.dis(h) 
    2   0 LOAD_FAST    0 (val) 
       3 LOAD_CONST    0 (None) 
       6 COMPARE_OP    9 (is not) 
       9 POP_JUMP_IF_FALSE  16 

    3   12 LOAD_GLOBAL    1 (True) 
      15 RETURN_VALUE 

    4  >> 16 LOAD_GLOBAL    2 (False) 
      19 RETURN_VALUE 

nota che gli ultimi due casi riducono alla stessa sequenza di operazioni (Python legge not (val is None) e utilizza l'operatore is not). Il primo utilizza l'operatore != quando si confronta con Nessuno.

Come sottolineato da altre risposte, utilizzando != quando si confrontano con nessuno di essi è una cattiva idea

+0

Qual è la differenza tra compare_op 9 e 3? – evolvedmicrobe

Problemi correlati