2011-07-04 33 views
14

Curiosamente:¿Cuándo usar == y cuándo usarlo?

>>> a = 123 
>>> b = 123 
>>> a is b 
True 
>>> a = 123. 
>>> b = 123. 
>>> a is b 
False 

Parece a is b siendo más o menos define como id(a) == id(b). Es fácil hacer errores de esta manera:

basename, ext = os.path.splitext(fname) 
if ext is '.mp3': 
    # do something 
else: 
    # do something else 

Algunos nombres inesperadamente terminaron en el bloque else. La solución es simple, deberíamos usar ext == '.mp3' en su lugar, pero no obstante if ext is '.mp3' en la superficie parece una buena forma pitónica para escribir esto y es más legible que la forma "correcta".

Dado que las cadenas son inmutables, ¿cuáles son los detalles técnicos de por qué está mal? ¿Cuándo es mejor una verificación de identidad y cuándo es mejor una verificación de igualdad?

+2

* relacionados con: * [? Python '==' vs '' se comparan cadenas, 'es' falla a veces, ¿por qué] (http://stackoverflow.com/questions/1504717/python-vs-is -comparing-strings-is-fails-sometimes-why) –

+0

posible duplicado de [¿Cuándo el operador \ '== \' no es equivalente al operador \ 'is \'? (Python)] (http://stackoverflow.com/questions/3647692/when-is-the-operator-not-equivalent-to-the-is-operator-python) – user

+0

relacionado: http://stackoverflow.com/ a/2577589/674039 – wim

Respuesta

5

Por lo que puedo decir, is comprueba la equivalencia de identidad del objeto. Como no hay obligatoria "cadena interna", dos cadenas que tienen los mismos caracteres en secuencia son, por lo general, no el mismo objeto de cadena.

Cuando extrae una subcadena de una cadena (o, realmente, cualquier subsecuencia de una secuencia), terminará con dos objetos diferentes, que contienen el mismo valor (es).

Por lo tanto, use is cuando y solo cuando compara identidades de objeto. Use == al comparar valores.

+3

En realidad, hay _es_interno de cadenas. Simplemente no sucederá para cadenas creadas dinámicamente. – katrielalex

+0

@katrielalex existe un 'interno interno()' que le permite * explícitamente * intern cadena dinámicamente creada; simplemente no sucede por sí mismo. – Duncan

+1

@katriealex: Creo que en realidad quise decir "interferencia automática y obligatoria de cadenas" (hay, creo, algunos idiomas que sí lo hacen). – Vatine

20

Son fundamentalmente diferentes.

  1. == compara llamando al método __eq__
  2. is devuelve verdadero si y sólo si las dos referencias son al mismo objeto

Así, en comparación con, por ejemplo Java:

  1. is es lo mismo que == para objetos
  2. == es el mismo que para los objetos equals
6

regla simple para determinar si el uso es o == en Python

Aquí es una regla fácil (a menos que quiera ir a la teoría en Python intérprete o crear frameworks haciendo cosas graciosas con objetos Python):

Usar solo para Ninguna comparación.

if foo is None 

De lo contrario, use ==.

if x == 3 

Entonces usted está en el lado seguro. La razón de esto ya se explica en los comentarios anteriores. No usar es si no está 100% seguro de por qué hacerlo.

+1

They Python way es un código legible, es decir, usa '==' siempre que eso es lo que quieres decir (casi siempre). 'is None'' if x: '' if not x: 'es la convención de Python para verificar' None True False' respectivamente. El uso real de 'is' se produce cuando se examinan estructuras de datos complejas, p. 'no afirme [l for l in mylist if l is mylist]' una simple comprobación contra ciclos en la estructura de datos (simple). –

+0

¿qué pasa con los tipos? 'type (" foo ") es str' probablemente sea correcto –

0

También sería útil definir una clase como esta para ser utilizada como valor predeterminado para las constantes utilizadas en su API.En este caso, sería más correcto usar es que el operador ==.

class Sentinel(object): 
    """A constant object that does not change even when copied.""" 
    def __deepcopy__(self, memo): 
     # Always return the same object because this is essentially a constant. 
     return self 

    def __copy__(self): 
     # called via copy.copy(x) 
     return self 
Cuestiones relacionadas