Kann man eines davon in Python 3 aktualisieren und das Skript tatsächlich funktionieren lassen?
Charlie Parker
Antworten:
172
Jedes von diesen gibt ein Wörterbuch zurück:
globals() Gibt immer das Wörterbuch des Modul- Namespace zurück
locals() Gibt immer ein Wörterbuch des aktuellen Namespace zurück
vars()Gibt entweder ein Wörterbuch des aktuellen Namespace (falls ohne Argument aufgerufen) oder das Wörterbuch des Arguments zurück.
localsund varskönnte etwas mehr Erklärung gebrauchen. Wenn locals()es innerhalb einer Funktion aufgerufen wird, aktualisiert es ein Diktat mit den Werten des aktuellen lokalen Variablennamensraums (plus aller Abschlussvariablen) ab diesem Moment und gibt es zurück. Mehrere Aufrufe an locals()denselben Stapelrahmen geben jedes Mal dasselbe Diktat zurück - es wird als f_localsAttribut an das Stapelrahmenobjekt angehängt . Der Inhalt des Diktats wird bei jedem locals()Aufruf und jedem f_localsAttributzugriff aktualisiert , jedoch nur bei solchen Aufrufen oder Attributzugriffen. Es wird nicht automatisch aktualisiert, wenn Variablen zugewiesen werden, und das Zuweisen von Einträgen im Diktat weist nicht die entsprechenden lokalen Variablen zu:
import inspectdef f():
x =1
l = locals()print(l)
locals()print(l)
x =2print(x, l['x'])
l['x']=3print(x, l['x'])
inspect.currentframe().f_localsprint(x, l['x'])
f()
gibt uns:
{'x':1}{'x':1,'l':{...}}212322
Der erste print(l)zeigt nur einen 'x'Eintrag, da die Zuordnung lnach dem locals()Anruf erfolgt. Die zweite print(l)zeigt nach erneutem Aufruf locals()einen lEintrag, obwohl wir den Rückgabewert nicht gespeichert haben. Das dritte und vierte prints zeigen, dass das Zuweisen von Variablen nicht aktualisiert wird lund umgekehrt, aber nach dem Zugriff f_localswerden lokale Variablen locals()erneut kopiert .
Zwei Anmerkungen:
Dieses Verhalten ist CPython-spezifisch. Bei anderen Pythons können die Aktualisierungen möglicherweise automatisch zum lokalen Namespace zurückkehren.
In CPython 2.x ist es möglich, dass dies funktioniert, indem eine exec "pass"Zeile in die Funktion eingefügt wird. Dies schaltet die Funktion in einen älteren, langsameren Ausführungsmodus um, der das locals()Diktat als kanonische Darstellung lokaler Variablen verwendet.
Wenn locals()es außerhalb einer Funktion aufgerufen wird , gibt es das tatsächliche Wörterbuch zurück, das der aktuelle Namespace ist. Weitere Änderungen im Namensraum sind im Wörterbuch reflektiert und Änderungen im Wörterbuch sind im Namensraum wider:
classTest(object):
a ='one'
b ='two'
huh = locals()
c ='three'
huh['d']='four'print huh
Bisher gilt alles, worüber ich gesagt habe, locals()auch für vars()... hier ist der Unterschied: vars()Akzeptiert ein einzelnes Objekt als Argument, und wenn Sie ihm ein Objekt geben, gibt es __dict__das Objekt zurück. Bei einem typischen Objekt werden __dict__hier die meisten Attributdaten gespeichert. Dies umfasst Klassenvariablen und Modulglobale:
classTest(object):
a ='one'
b ='two'def frobber(self):print self.c
t =Test()
huh = vars(t)
huh['c']='three'
t.frobber()
was uns gibt:
three
Beachten Sie, dass eine Funktion __dict__ihr Attribut-Namespace ist, keine lokalen Variablen. Es wäre für eine Funktion nicht sinnvoll __dict__, lokale Variablen zu speichern, da Rekursion und Multithreading bedeuten, dass mehrere Funktionen gleichzeitig aufgerufen werden können, wobei jeder seine eigenen Ortsansässigen hat:
Hier fruft sich selbst rekursiv, so dass die inneren und äußeren Anrufe überlappen. Jeder sieht seine eigenen lokalen Variablen, wenn er aufruft locals(), aber beide Aufrufe sehen dasselbe f.__dict__und enthalten f.__dict__keine lokalen Variablen.
Der Teil "und alle Zuweisungen zum Wörterbuch spiegeln sich nicht im tatsächlichen lokalen Namespace wider" ist möglicherweise etwas zu genau formuliert .
Sven Marnach
Seltsamerweise können Sie auf Variablen zugreifen, die einem vars()oder einem locals()Wörterbuch hinzugefügt wurden, das innerhalb einer Funktion aufgerufen wird, wenn Sie diese verwenden eval(). EG: def test(): huh = locals(); huh['d'] = 4; print eval('d')druckt 4, wenn test()ausgeführt wird!
Mark Mikofski
1
Die tatsächliche Zuordnung zum dict(zurückgegeben von locals()) spiegelt sich zufällig im lokalen Namespace wider, und Änderungen am lokalen Namespace spiegeln sich zufällig im dict(in meinem Python) wider . Das einzige ist, dass die Spezifikation dieses Verhalten nicht garantiert.
Skyking
Begriff Name Umfang Nutzung sieht für mich leichter , als Namespace .
Überaustausch
1
@overexchange: import thisund in Googlesite:docs.python.org namespace
Antworten:
Jedes von diesen gibt ein Wörterbuch zurück:
globals()
Gibt immer das Wörterbuch des Modul- Namespace zurücklocals()
Gibt immer ein Wörterbuch des aktuellen Namespace zurückvars()
Gibt entweder ein Wörterbuch des aktuellen Namespace (falls ohne Argument aufgerufen) oder das Wörterbuch des Arguments zurück.locals
undvars
könnte etwas mehr Erklärung gebrauchen. Wennlocals()
es innerhalb einer Funktion aufgerufen wird, aktualisiert es ein Diktat mit den Werten des aktuellen lokalen Variablennamensraums (plus aller Abschlussvariablen) ab diesem Moment und gibt es zurück. Mehrere Aufrufe anlocals()
denselben Stapelrahmen geben jedes Mal dasselbe Diktat zurück - es wird alsf_locals
Attribut an das Stapelrahmenobjekt angehängt . Der Inhalt des Diktats wird bei jedemlocals()
Aufruf und jedemf_locals
Attributzugriff aktualisiert , jedoch nur bei solchen Aufrufen oder Attributzugriffen. Es wird nicht automatisch aktualisiert, wenn Variablen zugewiesen werden, und das Zuweisen von Einträgen im Diktat weist nicht die entsprechenden lokalen Variablen zu:gibt uns:
Der erste
print(l)
zeigt nur einen'x'
Eintrag, da die Zuordnungl
nach demlocals()
Anruf erfolgt. Die zweiteprint(l)
zeigt nach erneutem Aufruflocals()
einenl
Eintrag, obwohl wir den Rückgabewert nicht gespeichert haben. Das dritte und vierteprint
s zeigen, dass das Zuweisen von Variablen nicht aktualisiert wirdl
und umgekehrt, aber nach dem Zugrifff_locals
werden lokale Variablenlocals()
erneut kopiert .Zwei Anmerkungen:
exec "pass"
Zeile in die Funktion eingefügt wird. Dies schaltet die Funktion in einen älteren, langsameren Ausführungsmodus um, der daslocals()
Diktat als kanonische Darstellung lokaler Variablen verwendet.Wenn
locals()
es außerhalb einer Funktion aufgerufen wird , gibt es das tatsächliche Wörterbuch zurück, das der aktuelle Namespace ist. Weitere Änderungen im Namensraum sind im Wörterbuch reflektiert und Änderungen im Wörterbuch sind im Namensraum wider:gibt uns:
Bisher gilt alles, worüber ich gesagt habe,
locals()
auch fürvars()
... hier ist der Unterschied:vars()
Akzeptiert ein einzelnes Objekt als Argument, und wenn Sie ihm ein Objekt geben, gibt es__dict__
das Objekt zurück. Bei einem typischen Objekt werden__dict__
hier die meisten Attributdaten gespeichert. Dies umfasst Klassenvariablen und Modulglobale:was uns gibt:
Beachten Sie, dass eine Funktion
__dict__
ihr Attribut-Namespace ist, keine lokalen Variablen. Es wäre für eine Funktion nicht sinnvoll__dict__
, lokale Variablen zu speichern, da Rekursion und Multithreading bedeuten, dass mehrere Funktionen gleichzeitig aufgerufen werden können, wobei jeder seine eigenen Ortsansässigen hat:was uns gibt:
Hier
f
ruft sich selbst rekursiv, so dass die inneren und äußeren Anrufe überlappen. Jeder sieht seine eigenen lokalen Variablen, wenn er aufruftlocals()
, aber beide Aufrufe sehen dasselbef.__dict__
und enthaltenf.__dict__
keine lokalen Variablen.quelle
vars()
oder einemlocals()
Wörterbuch hinzugefügt wurden, das innerhalb einer Funktion aufgerufen wird, wenn Sie diese verwendeneval()
. EG:def test(): huh = locals(); huh['d'] = 4; print eval('d')
druckt 4, wenntest()
ausgeführt wird!dict
(zurückgegeben vonlocals()
) spiegelt sich zufällig im lokalen Namespace wider, und Änderungen am lokalen Namespace spiegeln sich zufällig imdict
(in meinem Python) wider . Das einzige ist, dass die Spezifikation dieses Verhalten nicht garantiert.import this
und in Googlesite:docs.python.org namespace