2017-01-24 1 views
9

Wenn er in einer Python interaktive Sitzung:Python nicht im interaktiven Modus Strings internieren?

In [1]: a = "my string" 

In [2]: b = "my string" 

In [3]: a == b 
Out[3]: True 

In [4]: a is b 
Out[4]: False 

In [5]: import sys 

In [6]: print(sys.version) 
3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] 

Auf der anderen Seite, wenn Sie das folgende Programm ausgeführt wird:

#!/usr/bin/env python 

import sys 


def test(): 
    a = "my string" 
    b = "my string" 
    print(a == b) 
    print(a is b) 


if __name__ == "__main__": 
    test() 
    print(sys.version) 

Die Ausgabe lautet:

True 
True 
3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] 

Warum a is b hat anderes Ergebnis in den obigen zwei Fällen?

Ich bin mir dessen bewusst this Antwort (und natürlich der Unterschied zwischen den == und is Betreiber!, die den Punkt der Frage ist!), Sind aber nicht a und b das gleiche Objekt auch im ersten Fall? (Interpeter?), da sie auf die gleiche (unveränderliche) Saite zeigen?

+1

Mögliche Duplikate von [Gibt es einen Unterschied zwischen \ '== \' und \ 'is \' in Python?] (Http://stackoverflow.com/questions/132988/is-there-a-difference-between) -und-ist-in-python) – Juggernaut

+1

Sie müssten den cpython-Quellcode überprüfen, aber ich würde mir vorstellen, dass der Python-Interpreter intelligent genug ist, um zu erkennen, dass diese Strings identisch sind und Strings unveränderlich sind Zeige beide Variablen auf die gleiche Instanz. Daher gibt ein 'ist'-Test wahr zurück. Für die REPL, da die Strings inkrementell eingegeben werden, gibt es keine solche Optimierungsmöglichkeit und beide Variablen beziehen sich auf unterschiedliche Objekte. –

+4

@AminEtesamian Von dem, was ich verstehe, ist die Frage eher, warum die IDs bei der Verwendung von Interpreter unterscheidet, aber die gleichen sind beim Ausführen einer .py-Datei. Ich denke, Pkaramol versteht den Unterschied zwischen ist und ==. – HolyDanna

Antwort

8

Dies wird durch string interning verursacht. Ein anderes Beispiel finden Sie in this question.

In Ihrem Beispiel trainiert CPython die Stringkonstanten im Modul, aber nicht in der REPL.

+2

Weitere Informationen finden Sie unter [this] (http://stackoverflow.com/a/25267946/2076832). – GRAYgoose124

+1

Korrektur. Dies ist kein String Interning bei Fehler.Dies hat mit der ständigen Faltung zu tun. Siehe [hier] (https://paste.pound-python.org/show/1lMKJxdj7mgR3doK98XS/) – GRAYgoose124

+0

@ GREYgoose124 ist richtig, Code-Objekte deduplizieren ihre Konstanten. Außerdem enthält die Beispielzeichenfolge ein Leerzeichen und ist standardmäßig nicht interniert. Bitte schreibe eine Antwort, ich werde meine löschen. – emulbreh

1

So erstellt die Konsole zwei verschiedene Objekte beim Erstellen von zwei Zeichenfolgen, aber der Interpreter, wenn Code in einer einzigen Funktion ausgeführt wird, wird den Speicherort der identischen Zeichenfolgen wiederverwenden. Hier ist, wie zu überprüfen, ob diese mit Ihnen geschieht:

a = "my string" 
b = "my string" 

print id(a) 
print id(b) 

Wenn diese beiden IDs gleich sind, dann a is bTrue zurückkehren, wenn nicht, dann wird es False

zurückkehren Sieht aus wie Sie Anaconda verwenden , also habe ich das in der Konsole überprüft und verschiedene IDs gefunden und dann eine Funktion in den Editor geschrieben und ausgeführt und die selben IDs bekommen.

Hinweis: Jetzt, da wir wissen, dass is bestimmt, ob zwei Variablenlabels im Speicher auf das gleiche Objekt zeigen, soll ich sagen, dass is sollte sparsam verwendet werden. Es wird normalerweise verwendet, um Singletons wie None a is None zum Beispiel zu vergleichen. Verwenden Sie es also nicht zum Vergleichen von Objekten, verwenden Sie ==, und implementieren Sie beim Erstellen von Klassen die Methode __eq__, sodass Sie den Operator == verwenden können.

Verwandte Themen