is
prüft Objektidentität und jede Implementierung von Python, wenn es buchstäbliche von unveränderlichen Typen trifft, ist vollkommen frei zu entweder ein neues Objekt dieses unveränderlichen Typs machen, oder suchen durch bestehende Objekte dieses Typs Prüfen Sie, ob einige von ihnen wiederverwendet werden können (indem Sie einen neuen Verweis auf dasselbe zugrunde liegende Objekt hinzufügen). Dies ist eine pragmatische Wahl der Optimierung und nicht unterliegen semantischen Einschränkungen, so sollte Ihr Code nie darauf angewiesen, welchen Weg eine Give-Implementierung nehmen kann (oder es könnte mit einem Bugfix/Optimierung Release von Python brechen!).
zum Beispiel vor:
>>> import dis
>>> def f():
... x = 'google.com'
... return x is 'google.com'
...
>>> dis.dis(f)
2 0 LOAD_CONST 1 ('google.com')
3 STORE_FAST 0 (x)
3 6 LOAD_FAST 0 (x)
9 LOAD_CONST 1 ('google.com')
12 COMPARE_OP 8 (is)
15 RETURN_VALUE
so in dieser speziellen Implementierung, innerhalb einer Funktion, ist Ihre Beobachtung nicht gelten und nur ein Objekt für die wörtliche (Wörtliche) gemacht, und zwar:
>>> f()
True
das ist Pragmatisch, weil innerhalb einer Funktion einen durch~~POS=TRUNC durch die lokale Tabelle von konstanten zu machen (zu etwas Speicher zu sparen, indem Sie nicht mehrere konstante unveränderliche Objekte zu machen, wo man genügt) ist ziemlich billig und schnell, und kann eine gute Leistungsrendite bieten, da die Funktion danach wiederholt aufgerufen werden kann.
Aber, ganz gleich Implementierung an der interaktiven Eingabeaufforderung (bearbeiten: Ich dachte ursprünglich dies auch auf einem Moduls oberster Ebene passieren würde, aber ein Kommentar von @Thomas stellte ich später rechts sehen):
macht sich nicht die Mühe, Speicher auf diese Weise zu speichern - die id
s sind unterschiedlich, dh unterschiedliche Objekte. Es gibt potentiell höhere Kosten und niedrigere Erträge und so sagen die Heuristiken des Optimierers dieser Implementierung, dass sie die Suche nicht stören und einfach weitermachen.
bearbeiten: auf Modul oberster Ebene, pro @Thomas' Beobachtung, da zB:
$ cat aaa.py
x = 'google.com'
y = 'google.com'
print id(x), id(y)
wieder sehen wir die Tisch-of-Konstanten-basierte Speicher-Optimierung in dieser Implementierung:
>>> import aaa
4291104 4291104
(Ende von Edit per @Thomas Beobachtung).
schließlich wieder auf der gleichen Umsetzung:
>>> x = 'google'
>>> y = 'google'
>>> id(x), id(y)
(2484672, 2484672)
die Heuristiken sind hier anders, weil die Zeichenkette „sieht aus wie könnte es ein Bezeichner sein“ - so könnte es Internierung in Betrieb erfordern, verwendet werden .. Englisch: www.mjfriendship.de/en/index.php?op...39&Itemid=32 So trainiert der Optimierer es trotzdem (und wenn man einmal interniert ist, wird es natürlich sehr schnell) Und in der Tat, was für eine Überraschung ...:
>>> z = intern(x)
>>> id(z)
2484672
... x
hat gewesen intern
das erste Mal ed (wie Sie sehen, ist der Rückgabewert von intern
ist das gleiche Objekt als x
und y
, wie es das gleiche hat id()
). Natürlich sollten Sie sich auch nicht darauf verlassen - der Optimierer hat nicht automatisch alles zu internieren, es ist nur eine Optimierungsheuristik; Wenn Sie intern
ed String, intern
explizit benötigen, nur um sicher zu sein. Wenn Sie explizit intern Strings tun ...:
>>> x = intern('google.com')
>>> y = intern('google.com')
>>> id(x), id(y)
(4213000, 4213000)
... dann Sie tun sicherzustellen, die genau das gleiche Objekt (dh gleiche id()
) Ergebnisse jedes Mal - so können Sie micro anwenden Optimierungen wie das Überprüfen mit is
statt ==
(ich habe den winzigen Leistungsgewinn kaum je gefunden, der Aufwand lohnt sich ;-).
bearbeiten: nur zu klären, sind hier die Art der Leistungsunterschiede ich rede, auf einem langsamen Macbook Air ...:
$ python -mtimeit -s"a='google';b='google'" 'a==b'
10000000 loops, best of 3: 0.132 usec per loop
$ python -mtimeit -s"a='google';b='google'" 'a is b'
10000000 loops, best of 3: 0.107 usec per loop
$ python -mtimeit -s"a='goo.gle';b='goo.gle'" 'a==b'
10000000 loops, best of 3: 0.132 usec per loop
$ python -mtimeit -s"a='google';b='google'" 'a is b'
10000000 loops, best of 3: 0.106 usec per loop
$ python -mtimeit -s"a=intern('goo.gle');b=intern('goo.gle')" 'a is b'
10000000 loops, best of 3: 0.0966 usec per loop
$ python -mtimeit -s"a=intern('goo.gle');b=intern('goo.gle')" 'a == b'
10000000 loops, best of 3: 0.126 usec per loop
... ein paar Dutzend Nanosekunden entweder übrigens, höchstens. Also, im Wert von sogar Denken über nur in den extremsten "optimieren Sie die [Kraftausdruck gelöscht] aus diesem [Kraftausdruck] Performance-Engpass" Situationen! -)
Schöner Fang. Das ist seltsam. –
Beide sind in Python 2.5.2 "Falsch". –
In ActivePython 2.5.4.4 werden die gleichen Ergebnisse wie für OP angezeigt. Hat mit Sicherheit etwas mit String Interning zu tun, oder? –