with tutorial framework español djangoproject desde con cero applications python python-datamodel built-in

python - framework - tutorial django



¿Cómo se implementa la palabra clave ''is'' en Python? (10)

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

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

Intenté 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 >>>


''es'' compara identidad de objeto mientras que == compara 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


El operador is es equivalente a comparar valores de id(x) . id está actualmente implementado para usar punteros como comparación. Así que no puedes sobrecargar en sí mismo, y AFAIK tampoco puedes sobrecargar el id .

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


Estás usando una comparación de identidad. == es probablemente lo que quieres. La excepción a esto es cuando desea verificar si un elemento y otro son el mismo objeto EXACTO y en la misma posición de memoria. En los ejemplos, los elementos no son los mismos, ya que uno es de un tipo diferente (my_string) que el otro (cadena). Además, no existe tal cosa como una clase. __is__ en python (a menos que, por supuesto, lo pongas ahí mismo). Si lo hubiera, comparar los objetos con es no sería confiable simplemente comparar las ubicaciones de la memoria.

La primera vez que me encontré con la palabra clave es , me confundió también. Hubiera pensado que es así y == no fueron diferentes. Produjeron el mismo resultado del intérprete en muchos objetos. Este tipo de suposición es EXACTAMENTE lo que es ... es para. Es el equivalente de pitón "Oye, no confundas estos dos objetos, son diferentes", que es esencialmente lo que dijo [quien sea que me enderezó]. Encabezado de manera muy diferente, pero un punto == el otro punto.

Para algunos ejemplos útiles y algunos textos para ayudar con las diferencias a veces confusas, visite un documento del host de python.org escrito por "Danny Yoo"

o, si eso no está en línea, usa el pastebin no listado que hice de su cuerpo.

en caso de que, en unas 20 lunas azules (las lunas azules son un evento real), ambas estén caídas, citaré los ejemplos del 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 ###


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

Que es, creo, por qué no hay un mecanismo para proporcionar su propia implementación.

Resulta que a veces funciona en cadenas porque Python almacena cadenas ''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 referencia vs datos en un simple ejemplo de ''copia'':

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


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

>>> a == b

va a evaluar a

True

Pero si

>>> a is b

evalúa a

False

probablemente deberías verificar

>>> type(a)

y

>>> type(b)

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


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


Probar cadenas de caracteres solo funciona cuando las cadenas están intercaladas. A menos que realmente sepa lo que está haciendo e interned explícitamente las cadenas que nunca debería usar is en cadenas.

is pruebas de identidad , no de igualdad . Eso significa que Python simplemente compara la dirección de memoria en la que reside un objeto. 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 False . Por lo general, Python escribe cada cadena en una ubicación de memoria diferente, la internación ocurre principalmente para los literales de cadena.


Python is identidad del objeto de las pruebas de palabras clave. NO debes usarlo para probar la igualdad de cuerdas. Puede parecer que funciona con frecuencia porque las implementaciones de Python, como las de muchos lenguajes de muy alto nivel, realizan "interning" de cadenas de caracteres. Es decir que los literales y valores de cadena se mantienen internamente en una lista hash y los que son idénticos se representan como referencias al mismo objeto. (Esto es posible porque las cadenas de Python 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 quiere probar la identidad del objeto, entonces use --- y me costaría mucho crear un caso en el que se preocupe por la identidad del objeto de cadena. Lamentablemente, no se puede contar si dos cadenas son, de alguna manera, referencias de objetos "intencionalmente" idénticas debido a la internación antes mencionada.


Si no tiene miedo de equivocarse con bytecode, puede interceptar y aplicar parche a COMPARE_OP con el COMPARE_OP 8 ("is") para llamar a su función de COMPARE_OP en los objetos que se comparan. Mire la documentación del módulo dis para comenzar.

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


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

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