tutorial lenguaje instalar descargar python

python - lenguaje - ¿Hay alguna diferencia entre “foo is None” y “foo== None”?



python tutorial (11)

¿Hay alguna diferencia entre:

if foo is None: pass

y

if foo == None: pass

La convención que he visto en la mayoría de los códigos Python (y el código que escribo yo mismo) es el primero, pero recientemente encontré un código que usa el último. Ninguna es una instancia (y la única, IIRC) de NoneType, por lo que no debería importar, ¿verdad? ¿Hay alguna circunstancia en la que pueda hacerlo?


@ Jason :

Recomiendo usar algo más en la línea de

if foo: #foo isn''t None else: #foo is None

No me gusta usar "if foo:" a menos que foo realmente represente un valor booleano (es decir, 0 o 1). Si foo es una cadena o un objeto u otra cosa, "if foo:" puede funcionar, pero me parece un atajo perezoso. Si está comprobando si x es Ninguno, diga "si x es Ninguno:".


Algunos detalles más:

  1. La cláusula is realmente comprueba si los dos object están en la misma ubicación de memoria o no. es decir, si ambos apuntan a la misma ubicación de memoria y tienen la misma id .

  2. Como consecuencia de 1, is garantiza si, o no, los dos object representados léxicamente tienen atributos idénticos (atributos de atributos ...) o no

  3. La creación de instancias de tipos primitivos como bool , int , string (con alguna excepción), NoneType con el mismo valor siempre estará en la misma ubicación de memoria.

P.ej

>>> int(1) is int(1) True >>> str("abcd") is str("abcd") True >>> bool(1) is bool(2) True >>> bool(0) is bool(0) True >>> bool(0) False >>> bool(1) True

Y dado que NoneType solo puede tener una instancia de sí mismo en la tabla de "consulta" de python, por lo tanto, el primero y el último son más un estilo de programación del desarrollador que escribió el código (quizás por coherencia) en lugar de tener una razón lógica sutil para elegir uno sobre el otro.


Es posible que desee leer esta identidad de objeto y equivalencia .

La declaración ''es'' se usa para la identidad del objeto, verifica si los objetos se refieren a la misma instancia (la misma dirección en la memoria).

Y la declaración ''=='' se refiere a la igualdad (mismo valor).


La conclusión de John Machin de que None es un singleton es una conclusión reforzada por este código.

>>> x = None >>> y = None >>> x == y True >>> x is y True >>>

Dado que None es un singleton, x == None y x is None tendrían el mismo resultado. Sin embargo, en mi opinión estética, x == None es la mejor.


La razón por la que foo is None es que la forma preferida es que podría estar manejando un objeto que define su propio __eq__ , y que define que el objeto es igual a None. Por lo tanto, siempre use foo is None si necesita ver si es infact None .


No hay diferencia porque los objetos que son idénticos, por supuesto, serán iguales. Sin embargo, PEP 8 indica claramente que debe usar is :

Las comparaciones con singletons como None deben hacerse siempre con o no, nunca con los operadores de igualdad.


Para Ninguno no debería haber una diferencia entre la igualdad (==) y la identidad (es). El NoneType probablemente devuelve la identidad para la igualdad. Dado que Ninguno es la única instancia que puede hacer de NingunoTipo (creo que esto es cierto), las dos operaciones son las mismas. En el caso de otros tipos, este no es siempre el caso. Por ejemplo:

list1 = [1, 2, 3] list2 = [1, 2, 3] if list1==list2: print "Equal" if list1 is list2: print "Same"

Esto imprimiría "Igual", ya que las listas tienen una operación de comparación que no es la devolución de identidad predeterminada.


Siempre devuelve True si compara la misma instancia de objeto.

Mientras que == está determinado en última instancia por el __eq__()

es decir

>>> class Foo(object): def __eq__(self, other): return True >>> f = Foo() >>> f == None True >>> f is None False


Una palabra de precaución:

if foo: # do something

No es exactamente lo mismo que:

if x is not None: # do something

El primero es una prueba de valor booleano y se puede evaluar como falso en diferentes contextos. Hay una serie de cosas que representan falso en una prueba de valor booleano, por ejemplo, contenedores vacíos, valores booleanos. Ninguno también se evalúa como falso en esta situación, pero otras cosas también lo hacen.


(ob1 is ob2) igual a (id(ob1) == id(ob2))


is pruebas de identidad, no de igualdad. Para su declaración, foo is none , Python simplemente compara la dirección de memoria de los objetos. Significa que está haciendo la pregunta "¿Tengo dos nombres para el mismo objeto?"

== por otra parte, prueba la igualdad según lo determinado por el __eq__() . No le importa la identidad.

In [102]: x, y, z = 2, 2, 2.0 In [103]: id(x), id(y), id(z) Out[103]: (38641984, 38641984, 48420880) In [104]: x is y Out[104]: True In [105]: x == y Out[105]: True In [106]: x is z Out[106]: False In [107]: x == z Out[107]: True

None es un operador de singleton. Así que None is None es siempre cierto.

In [101]: None is None Out[101]: True