Frage

... das is Schlüsselwort, das für Gleichheit in Saiten verwendet werden kann.

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

Ich habe beide versucht __is__() und __eq__() Aber sie haben nicht gearbeitet.

>>> 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
>>>
War es hilfreich?

Lösung

Testen von Saiten mit is funktioniert nur, wenn die Saiten interniert sind. Es sei denn, Sie wissen wirklich, was Sie tun und explizit interniert Die Saiten sollten Sie sollten noch nie verwenden is auf Saiten.

is Tests für Identität, nicht Gleichberechtigung. Das bedeutet, dass Python einfach die Speicheradresse vergleicht, in der ein Objekt liegt. is Beantwortet die Frage im Grunde: "Habe ich zwei Namen für dasselbe Objekt?" - Überlastung, das keinen Sinn ergibt.

Zum Beispiel, ("a" * 100) is ("a" * 100) ist FALSCH. Normalerweise schreibt Python jede Zeichenfolge in einen anderen Speicherort, und einsieht hauptsächlich für String -Literale.

Andere Tipps

Das is Der Bediener entspricht dem Vergleich id(x) Werte. id wird derzeit implementiert, um Zeiger als Vergleich zu verwenden. Sie können also nicht überlasten is selbst und Afaik können Sie nicht überlasten id entweder.

Also kannst du nicht. Ungewöhnlich in Python, aber da ist es.

Die Python is Schlüsselwort testet die Objektidentität. Sie sollten es nicht verwenden, um die Gleichstellung der Zeichenfolge zu testen. Es scheint häufig zu funktionieren, weil Python -Implementierungen wie die von vielen sehr hohen Sprachen "Einlagen" von Saiten ausführen. Das heißt, dass String -Literale und -Werte intern in einer Hashed -Liste aufbewahrt werden und die identischen Personen als Verweise auf dasselbe Objekt gerendert werden. (Dies ist möglich, weil Python -Saiten unveränderlich sind).

Wie bei allen Implementierungsdetails sollten Sie sich jedoch nicht darauf verlassen. Wenn Sie auf Gleichheit testen möchten, verwenden Sie den Operator ==. Wenn Sie wirklich auf Objektidentität testen möchten, verwenden Sie is --- und ich würde mich schwer fällt, einen Fall zu finden, in dem Sie sich für die Identität von String-Objekten kümmern sollten. Leider können Sie sich nicht darauf verlassen, ob zwei Saiten aufgrund der oben genannten Einkerbung irgendwie "absichtlich" identische Objektreferenzen sind.

Das is Das Schlüsselwort vergleicht Objekte (oder vielmehr vergleicht es, ob zwei Referenzen auf dasselbe Objekt sind).

Ich denke, warum es keinen Mechanismus gibt, um Ihre eigene Implementierung zu liefern.

Es funktioniert manchmal auf Saiten, da Python Saiten "geschickt" speichert, so dass sie, wenn Sie zwei identische Saiten erstellen, in einem Objekt gespeichert werden.

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

Sie können hoffentlich den Referenz -vs -Datenvergleich in einem einfachen 'Kopie' Beispiel sehen:

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

Wenn Sie keine Angst haben, sich mit Bytecode durcheinander zu bringen, können Sie abfangen und patchen COMPARE_OP mit 8 ("is") Argument, um Ihre Hakenfunktion auf den verglichenen Objekten aufzurufen. Ansehen dis Moduldokumentation für Start-in.

Und vergessen Sie nicht, abzufangen __builtin__.id() auch, wenn jemand tut id(a) == id(b) Anstatt von a is b.

Vergleicht eine String-Variable mit dem Zeichenfolgenwert und zwei String-Variablen nicht, wenn die Zeichenfolge mit '-' beginnt. Meine Python -Version ist 2.6.6

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

"Is" vergleicht Objektidentität, während == Werte vergleicht.

Beispiel:

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

Sie können das nicht überladen is Operator. Was Sie überladen möchten, ist die == Operator. Dies kann durch Definieren von a erfolgen __eq__ Methode in der Klasse.

Sie verwenden Identitätsvergleich. == ist wahrscheinlich was du willst. Die Ausnahme davon ist, wenn Sie überprüfen möchten, ob ein Element und ein anderes genau das gleiche Objekt und in derselben Speicherposition sind. In Ihren Beispielen sind die Artikel nicht gleich, da einer von einem anderen Typ (my_string) als der andere (Zeichenfolge) ist. Es gibt auch keine Someclass.__is__ In Python (es sei denn natürlich, Sie setzen es selbst dort). Wenn es gab, vergleichen Sie Objekte mit ist Wäre nicht zuverlässig, um einfach die Speicherorte zu vergleichen.

Als ich zum ersten Mal begegnete ist Schlüsselwort, es hat mich auch verwirrt. Ich hätte das gedacht ist und == waren nicht anders. Sie produzierten die gleiche Ausgabe aus dem Dolmetscher an vielen Objekten. Diese Art von Annahme ist eigentlich genau was ist... ist für. Es ist das Python -Äquivalent "Hey, verwechseln Sie diese beiden Objekte nicht. Sie sind unterschiedlich." Viel anders formuliert, aber ein Punkt == der andere Punkt.

Das für einige hilfreiche Beispiele und einige Text, um den manchmal verwirrenden Unterschied zu besuchen Ein Dokument von Python.orgs Mail -Host von Python.org Geschrieben von "Danny Yoo"

Oder, wenn das offline ist, verwenden Sie die Unlisted Pastebin Ich habe aus seinem Körper gemacht.

Falls sie in etwa 20 blauen Monden (blaue Monde sind ein echtes Ereignis), zitieren ich die Code -Beispiele

###
>>> 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
###

Behauptungsfehler können leicht auftreten mit ist Schlüsselwort beim Vergleich von Objekten. Zum Beispiel Objekte a und b Könnte den gleichen Wert haben und die gleiche Speicheradresse teilen. Deshalb eins

>>> a == b

wird bewerten zu

True

Doch wenn

>>> a is b

bewertet

False

Sie sollten wahrscheinlich überprüfen

>>> type(a)

und

>>> type(b)

Diese können unterschiedlich sein und ein Grund für ein Scheitern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top