Da die Zeichenfolge unveränderlich ist (genau wie ein Tupel), wird sie zusammen mit dem Bytecode-Objekt für die Funktion gespeichert. Es wird durch eine sehr einfache und schnelle Indexsuche geladen. Dies ist eigentlich schneller als eine globale Suche.
Sie können sehen, in einer Zerlegung des Bytecode, mit dem dis.dis()
function:
>>> import dis
>>> def foo(s):
... c_string = "hello"
... if s == c_string:
... return True
... return False
...
>>> dis.dis(foo)
2 0 LOAD_CONST 1 ('hello')
3 STORE_FAST 1 (c_string)
3 6 LOAD_FAST 0 (s)
9 LOAD_FAST 1 (c_string)
12 COMPARE_OP 2 (==)
15 POP_JUMP_IF_FALSE 22
4 18 LOAD_GLOBAL 0 (True)
21 RETURN_VALUE
5 >> 22 LOAD_GLOBAL 1 (False)
25 RETURN_VALUE
>>> foo.__code__.co_consts
(None, 'hello')
Der LOAD_CONST
Opcode das String-Objekt aus dem co_costs
Array lädt, den Teil des Codeobjekts für die Funktion ist; Die Referenz wird an den Anfang des Stapels geschoben. Der Opcode STORE_FAST
nimmt den Verweis von der Oberseite des Stapels und speichert ihn in dem lokalen Array, wiederum eine sehr einfache und schnelle Operation.
Für wandelbar Literale ({..}
, [..]
) spezielle OP-Codes bauen das Objekt, mit dem Inhalt noch als Konstanten behandelt, so viel wie möglich (komplexere Strukturen nur den gleichen Bausteine folgen):
>>> def bar(): return ['spam', 'eggs']
...
>>> dis.dis(bar)
1 0 LOAD_CONST 1 ('spam')
3 LOAD_CONST 2 ('eggs')
6 BUILD_LIST 2
9 RETURN_VALUE
Die BUILD_LIST
call erstellt das neue Listenobjekt mit zwei konstanten String-Objekten.
Interessanter Fakt: Wenn Sie ein Listenobjekt für einen Mitgliedschaftstest verwendet haben (something in ['option1', 'option2', 'option3']
) Python weiß, dass das Listenobjekt niemals mutiert wird und es zur Compilierzeit in ein Tupel konvertiert (eine sogenannte Peephole-Optimierung) Gleiches gilt für eine Reihe wörtlichen, die zu einem frozenset()
Objekt umgewandelt wird, aber nur in Python 3.2 und neueren Tuple or list when using 'in' in an 'if' clause?
Hinweis sehen, dass Ihre Beispielfunktion booleans eher verbosely verwendet, man konnte nur verwendet.
def foo(s):
c_string = "hello"
return s == c_string
für genau das gleiche Ergebnis, diezu vermeidenAnrufe in Python 2 (Python 3 gemacht True
und False
Schlüsselwörter, so dass die Werte auch als Konstanten gespeichert werden können).
Ist nicht das Gleiche geschieht mit 's ==„Hallo“'? – jonrsharpe
Sie haben Recht mit dem Kommentar zu Tupel, ich hätte stattdessen nach einer Liste fragen sollen. Ich werde die Frage korrigieren. Der Rest der Antwort ist für jetzt hervorragend :) –
@ArthurVaiselbuh: Ich habe jetzt auch Listen abgedeckt, sowie '{...}' Wörterbücher und Sets. –