Pregunta

... la is Palabra clave que se puede usar para la igualdad en cadenas.

>>> s = 'str'
>>> s is 'str'
True
>>> s is 'st'
False

Probé ambos __is__() y __eq__() Pero no funcionaron.

>>> class MyString:
...   def __init__(self):
...     self.s = 'string'
...   def __is__(self, s):
...     return self.s == s
...
>>>
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work
False
>>>
>>> class MyString:
...   def __init__(self):
...     self.s = 'string'
...   def __eq__(self, s):
...     return self.s == s
...
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work, but again failed
False
>>>
¿Fue útil?

Solución

Pruebas de cadenas con is Solo funciona cuando las cuerdas son internadas. A menos que realmente sepas lo que estás haciendo y explícitamente interno las cadenas que deberías nunca usar is en cuerdas.

is pruebas para identidad, no igualdad. Eso significa que Python simplemente compara la dirección de memoria en la que reside un objeto. is Básicamente responde a la pregunta "¿Tengo dos nombres para el mismo objeto?" - Sobrecarga que no tendría sentido.

Por ejemplo, ("a" * 100) is ("a" * 100) es Falso. Por lo general, Python escribe cada cadena en una ubicación de memoria diferente, la interno ocurre principalmente para literales de cadena.

Otros consejos

los is El operador es equivalente a comparar id(x) valores. id actualmente se implementa para usar punteros como comparación. Para que no puedas sobrecargar is en sí, y afaik no puedes sobrecargar id o.

Entonces, no puedes. Inusual en Python, pero ahí está.

El pitón is La palabra clave prueba la identidad del objeto. No debe usarlo para probar la igualdad de cadenas. Puede parecer funcionar con frecuencia porque las implementaciones de Python, como las de muchos idiomas de muy alto nivel, realizan una "intermedio" de las cuerdas. Es decir que los literales y valores de cadena se mantienen internamente en una lista de hash y los que son idénticos se representan como referencias al mismo objeto. (Esto es posible porque las cadenas de pitón son inmutables).

Sin embargo, como con cualquier detalle de implementación, no debe confiar en esto. Si desea probar la igualdad, use el operador ==. Si realmente desea probar la identidad de los objetos, use is --- y sería difícil encontrar un caso en el que deba preocuparte por la identidad de los objetos de cadena. Desafortunadamente, no puede contar con si dos cadenas son de alguna manera referencias de objetos "intencionalmente" "intencionalmente" debido a la prestación mencionada anteriormente.

los is La palabra clave compara objetos (o, más bien, se compara si dos referencias son al mismo objeto).

Es decir, creo, por qué no hay mecanismo para proporcionar su propia implementación.

A veces funciona en cadenas porque Python almacena cuerdas "inteligentemente", de modo que cuando creas dos cadenas idénticas se almacenan en un objeto.

>>> a = "string"
>>> b = "string"
>>> a is b
True
>>> c = "str"+"ing"
>>> a is c
True

Con suerte, puede ver la comparación de datos de referencia frente a los datos en un simple ejemplo de 'copia':

>>> a = {"a":1}
>>> b = a
>>> c = a.copy()
>>> a is b
True
>>> a is c
False

Si no tiene miedo de estropear con bytecode, puede interceptar y parchear COMPARE_OP con 8 ("is") argumento para llamar a su función de gancho en los objetos que se comparan. Mirar dis Documentación del módulo para inicio.

Y no olvides interceptar __builtin__.id() también si alguien lo hará id(a) == id(b) en vez de a is b.

IS no puede comparar una variable de cadena con el valor de cadena y dos variables de cadena cuando la cadena comienza con '-'. Mi versión de Python es 2.6.6

>>> s = '-hi'
>>> s is '-hi'
False 
>>> s = '-hi'
>>> k = '-hi'
>>> s is k 
False
>>> '-hi' is '-hi'
True

'IS' compara la identidad del objeto, mientras que == compara los valores.

Ejemplo:

a=[1,2]
b=[1,2]
#a==b returns True
#a is b returns False

p=q=[1,2]
#p==q returns True
#p is q returns True

No puedes sobrecargar el is operador. Lo que quieres sobrecargar es el == operador. Esto se puede hacer definiendo un __eq__ Método en la clase.

Estás utilizando la comparación de identidad. == es probablemente lo que quieres. La excepción a esto es cuando desea verificar si un elemento y otro son exactamente el mismo objeto y en la misma posición de memoria. En sus ejemplos, los elementos no son los mismos, ya que uno es de un tipo diferente (my_string) que el otro (cadena). Además, no hay tal cosa como Someclass.__is__ En Python (a menos, por supuesto, lo pones allí tú mismo). Si hubiera, comparando objetos con es No sería confiable simplemente para comparar las ubicaciones de memoria.

Cuando encontré por primera vez el es Palabra clave, también me confundió. Hubiera pensado que es y == no fueron diferentes. Produjeron la misma salida del intérprete en muchos objetos. Este tipo de suposición es en realidad exactamente lo que es... es para. Es el equivalente de Python "Oye, no confundas estos dos objetos. Son diferentes", que es esencialmente lo que [quien sea que me enderezó] dijo. Redactado de manera muy diferente, pero un punto == el otro punto.

para algunos ejemplos útiles y algún texto para ayudar con la visita a veces confusa de las diferencias Un documento de Python.org's Mail Host Escrito por "Danny Yoo"

o, si eso está fuera de línea, use el pastebin sin listones Hice de su cuerpo.

En caso de que, en unas 20 lunas azules (las lunas azules son un evento real), están abajo, citaré los ejemplos de código

###
>>> my_name = "danny"
>>> your_name = "ian"
>>> my_name == your_name
0                #or False
###

###
>>> my_name[1:3] == your_name[1:3]
1    #or True
###

###
>>> my_name[1:3] is your_name[1:3]
0
###

Los errores de afirmación pueden surgir fácilmente con es palabra clave al comparar objetos. Por ejemplo, objetos a y b podría tener el mismo valor y compartir la misma dirección de memoria. Por lo tanto, haciendo un

>>> a == b

va a evaluar para

True

Pero si

>>> a is b

evaluar

False

Probablemente deberías comprobar

>>> type(a)

y

>>> type(b)

Estos pueden ser diferentes y una razón para el fracaso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top