¿Existe alguna diferencia entre "foo es Ninguno" y "foo == Ninguno"?

StackOverflow https://stackoverflow.com/questions/26595

  •  09-06-2019
  •  | 
  •  

Pregunta

¿Hay alguna diferencia entre:

if foo is None: pass

y

if foo == None: pass

La convención que he visto en la mayoría del código Python (y en el código que yo mismo escribo) es la primera, pero recientemente encontré un código que usa la segunda.Ninguno es una instancia (y la única instancia, IIRC) de NoneType, por lo que no debería importar, ¿verdad?¿Hay alguna circunstancia en la que podría ser así?

¿Fue útil?

Solución

is siempre regresa True si compara la misma instancia de objeto

Mientras == está determinada en última instancia por la __eq__() método

es decir.


>>> class Foo(object):
       def __eq__(self, other):
           return True

>>> f = Foo()
>>> f == None
True
>>> f is None
False

Otros consejos

Quizás quieras leer esto. identidad y equivalencia del objeto.

La declaración 'is' 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).

Una palabra de precaución:

if foo:
  # do something

Es no exactamente el mismo que:

if x is not None:
  # do something

La primera es una prueba de valor booleano y puede evaluarse como falso en diferentes contextos.Hay una serie de cosas que representan falso en pruebas de valores booleanos, 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))

La razón foo is None La forma preferida es que podría estar manejando un objeto que define su propio __eq__, y eso define el objeto como igual a Ninguno.Por lo tanto, utilice siempre foo is None si necesitas ver si es de hecho None.

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

Las comparaciones con singletons como None siempre deben realizarse con is o not is, nunca con los operadores de igualdad.

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

== por otro lado, pruebas de igualdad determinadas por el __eq__() método.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 singleton.Entonces None is None siempre es cierto.

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

Para Ninguno no debería haber una diferencia entre igualdad (==) e identidad (es).El NoneType probablemente devuelve identidad por igualdad.Dado que None es la única instancia que puede crear de NoneType (creo que esto es cierto), las dos operaciones son iguales.En el caso de otros tipos esto no siempre es así.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.

@jason:

Recomiendo usar algo más parecido a

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, un objeto o algo más, "if foo:" puede funcionar, pero a mí me parece un atajo vago.Si está comprobando si x es Ninguno, diga "si x es Ninguno:".

Algunos detalles más:

  1. El is La cláusula realmente verifica si los dos objectS 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 lo mismo id.

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

  3. Creación de instancias de tipos primitivos como bool, int, string(con alguna excepción), NoneType tener 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 desde NoneType sólo puede tener una instancia de sí mismo en la tabla de "búsqueda" de Python, por lo tanto, el primero y el segundo son más un estilo de programación del desarrollador que escribió el código (tal vez por coherencia) en lugar de tener una razón lógica sutil para elegir uno. sobre el otro.

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

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

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

a is b # returns true if they a and b are true alias
a == b # returns true if they are true alias or they have values that are deemed equivalence 


a = [1,3,4]
b = a[:] #creating copy of list
a is b # if gives false
False
a == b # gives true
True
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top