2010-10-19 14 views

Respuesta

632
if val is not None: 
    # ... 

es la expresión idiomática para probar que una variable no está configurada en None. Este idioma tiene usos particulares en el caso de declaring keyword functions with default parameters. is prueba identidad en Python. Debido a que hay una y solo una instancia de None presente en un script/programa en ejecución de Python, is es la prueba óptima para esto. Como Johnsyweb points out, esto se trata en PEP 8 en "Recomendaciones de programación".

En cuanto a por qué esto se prefiere

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

esto es simplemente parte de los Zen of Python: "La legibilidad cuenta." Good Python suele estar cerca del bien pseudocode.

+38

también, "is not" tiene semeánticos especiales creados para este propósito (no es una consecuencia lógica de cómo se construyen las expresiones; "1 es (no None)" y "1 is Not None" tienen dos resultados diferentes. –

+13

+1: Me gustó esta referencia: "Good Python a menudo está cerca del pseudocódigo bueno" – legesh

+1

"not None" devuelve True. Interesante. – Ries

18

Cualquiera de los dos últimos, ya que val podría ser de un tipo que define __eq__() para devolver verdadero cuando pasó None.

+4

Eso es bastante ruin '__eq __()' comportamiento, y es algo que no había considerado. Buena respuesta para atrapar un caso de esquina. – gotgenes

74

De, recomendaciones de programación, PEP 8:

Las comparaciones con embarazos únicos como Ninguno siempre debe hacerse con 'es' o 'no es', nunca los operadores de igualdad.

Además, tenga cuidado de escribir "si x" cuando realmente quiere decir "si x no es ninguno" - por ejemplo, cuando se prueba si una variable o argumento que tiene como valor predeterminado Ninguno se configuró en algún otro valor. El otro valor podría tener un tipo (como un contenedor) que podría ser falso en un contexto booleano.

PEP 8 es lectura esencial para cualquier programador de Python.

+4

+1 para la "lectura esencial" - no sabía nada de eso – user2314737

12

La mejor apuesta con este tipo de preguntas es ver exactamente lo que hace python. El módulo dis es increíblemente 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 

Tenga en cuenta que los dos últimos casos se reducen a la misma secuencia de operaciones (Python lee not (val is None) y utiliza el operador is not). El primero usa el operador != al comparar con Ninguno.

Como se ha comentado en otras respuestas, utilizando != cuando se comparan con ninguna es una mala idea

+0

¿Cuál es la diferencia entre compare_op 9 y 3? – evolvedmicrobe

Cuestiones relacionadas