Was ist der Grund dafür, dass globals () in Python funktioniert? Es wird nur ein Wörterbuch globaler Variablen zurückgegeben, die bereits global sind, sodass sie überall verwendet werden können. Ich frage nur aus Neugier und versuche, Python zu lernen.
def F():
global x
x = 1
def G():
print(globals()["x"]) #will return value of global 'x', which is 1
def H():
print(x) #will also return value of global 'x', which, also, is 1
F()
G()
H()
Ich kann den Punkt hier nicht wirklich sehen? Ich würde es nur brauchen, wenn ich lokale und globale Variablen mit demselben Namen für beide hätte
def F():
global x
x = 1
def G():
x = 5
print(x) #5
print(globals()["x"]) #1
F()
G()
Sie sollten jedoch niemals auf das Problem stoßen, zwei Variablen mit demselben Namen zu haben und beide im selben Bereich verwenden zu müssen.
globals
ist vielleicht etwas irreführend.globals()
ist im Wesentlichen daslocals()
eines Moduls. Das__builtin__
Modul kommt dem Globalen am nächsten, das für Ihr gesamtes Programm wirklich global ist . Alles, was Sie diesem Modul hinzufügen, ist überall in allen Namespaces verfügbar.Antworten:
Python bietet dem Programmierer eine Vielzahl von Tools zur Überprüfung der laufenden Umgebung.
globals()
ist nur eine davon, und es kann in einer Debugging-Sitzung sehr nützlich sein, um zu sehen, welche Objekte der globale Bereich tatsächlich enthält.Ich bin mir sicher, dass
locals()
das Grundprinzip das gleiche ist wie das , um die in einer Funktion definierten Variablen anzuzeigen oderdir
um den Inhalt eines Moduls oder die Attribute eines Objekts anzuzeigen.Ich komme aus einem C ++ - Hintergrund und kann verstehen, dass diese Dinge unnötig erscheinen. In einer statisch verknüpften, statisch typisierten Umgebung wären sie es absolut. In diesem Fall ist zur Kompilierungszeit genau bekannt, welche Variablen global sind, welche Mitglieder ein Objekt haben wird und sogar welche Namen von einer anderen Kompilierungseinheit exportiert werden.
In einer dynamischen Sprache sind diese Dinge jedoch nicht festgelegt; Sie können sich je nach Import des Codes oder sogar zur Laufzeit ändern. Zumindest aus diesem Grund kann der Zugriff auf diese Art von Informationen in einem Debugger von unschätzbarem Wert sein.
quelle
globals
geändert werden (wahrscheinlich eine Funktion, die Experten am besten überlassen bleibt). Ebenfalls relevant dieses Zitat aus ist Dive Into Python „ , um die Verwendunglocals
undglobals
Funktionen können Sie den Wert von beliebigen Variablen dynamisch zu bekommen, als String den Variablennamen bereitstellt. Dies spiegelt die Funktionalität dergetattr
Funktion, die Sie für den Zugriff beliebige Funktionen dynamisch ermöglicht durch Bereitstellung des Funktionsnamens als Zeichenfolge. "Dies ist auch nützlich, wenn Sie eine Funktion unter Verwendung des Zeichenfolgennamens der Funktion aufrufen müssen. Zum Beispiel:
def foo(): pass function_name_as_string = 'foo' globals()[function_name_as_string]() # foo().
quelle
def foo(*args): print("hw", *args)
Sie tun:globals()['foo']()
oderglobals()['foo']('reason', 42)
usw.Sie können das Ergebnis von übergeben
globals()
undlocals()
an dieeval
,execfile
und__import__
Befehle. Dadurch wird eine eingeschränkte Umgebung geschaffen, in der diese Befehle ausgeführt werden können.Daher sind diese Funktionen vorhanden, um andere Funktionen zu unterstützen, die von einer Umgebung profitieren, die sich möglicherweise vom aktuellen Kontext unterscheidet. Sie können beispielsweise
globals()
einige Variablen aufrufen , dann entfernen oder hinzufügen, bevor Sie eine dieser Funktionen aufrufen.quelle
globals()
ist nützlich füreval()
- wenn Sie Code auswerten möchten, der sich auf Variablen im Gültigkeitsbereich bezieht, werden diese Variablen entweder global oder lokal angezeigt.Um ein wenig zu erweitern,
eval()
interpretiert die integrierte Funktion eine Zeichenfolge von Python-Code , die ihr zugewiesen wurde. Die Signatur lautet :eval(codeString, globals, locals)
, und Sie würden es so verwenden:def foo(): x = 2 y = eval("x + 1", globals(), locals()) print("y=" + y) # should be 3
Dies funktioniert, da der Interpreter den Wert von
x
aus demlocals()
Diktat der Variablen erhält . Sie können eval natürlich Ihr eigenes Diktat von Variablen zur Verfügung stellen.quelle
eval("x+1")
macht das Gleiche aufgrund seiner Standardparameter; siehehelp(eval)
globals()
verwendet werden kann: stackoverflow.com/a/22021058/9024698 .Es kann in 'deklarativem Python' nützlich sein. Zum Beispiel in dem unten
FooDef
undBarDef
werden verwenden Klassen eine Reihe von Datenstrukturen zu definieren , die dann durch ein Paket als seinen Eingang verwendet werden, oder seine Konfiguration. Dies ermöglicht Ihnen viel Flexibilität bei der Eingabe und Sie müssen keinen Parser schreiben.# FooDef, BarDef are classes Foo_one = FooDef("This one", opt1 = False, valence = 3 ) Foo_two = FooDef("The other one", valence = 6, parent = Foo_one ) namelist = [] for i in range(6): namelist.append("nm%03d"%i) Foo_other = FooDef("a third one", string_list = namelist ) Bar_thing = BarDef( (Foo_one, Foo_two), method = 'depth-first')
Beachten Sie, dass diese Konfigurationsdatei eine Schleife verwendet, um eine Liste von Namen zu erstellen, die Teil der Konfiguration von sind
Foo_other
. Diese Konfigurationssprache verfügt daher über einen sehr leistungsstarken Präprozessor mit einer verfügbaren Laufzeitbibliothek. Wenn Sie beispielsweise ein komplexes Protokoll suchen oder Dinge aus einer Zip-Datei extrahieren und von base64 dekodieren möchten, um Ihre Konfiguration zu generieren (dieser Ansatz wird natürlich nicht empfohlen, wenn die Eingabe möglicherweise von einem stammt nicht vertrauenswürdige Quelle ...)Das Paket liest die Konfiguration wie folgt:
conf_globals = {} # make a namespace # Give the config file the classes it needs conf_globals['FooDef']= mypkgconfig.FooDef # both of these are based ... conf_globals['BarDef']= mypkgconfig.BarDef # ... on .DefBase fname = "user.conf" try: exec open(fname) in conf_globals except Exception: ...as needed... # now find all the definitions in there # (I'm assuming the names they are defined with are # significant to interpreting the data; so they # are stored under those keys here). defs = {} for nm,val in conf_globals.items(): if isinstance(val,mypkgconfig.DefBase): defs[nm] = val
globals()
Wenn Sie also ein solches Paket verwenden , ist es hilfreich , endlich auf den Punkt zu kommen , wenn Sie eine Reihe von Definitionen prozedural prägen möchten:for idx in range(20): varname = "Foo_%02d" % i globals()[varname]= FooDef("one of several", id_code = i+1, scale_ratio = 2**i)
Dies entspricht dem Ausschreiben
Foo_00 = FooDef("one of several", id_code = 1, scale_ratio=1) Foo_01 = FooDef("one of several", id_code = 2, scale_ratio=2) Foo_02 = FooDef("one of several", id_code = 3, scale_ratio=4) ... 17 more ...
Ein Beispiel für ein Paket, das seine Eingabe durch Sammeln einer Reihe von Definitionen aus einem Python-Modul erhält, ist PLY (Python-lex-yacc) http://www.dabeaz.com/ply/ - in diesem Fall sind die Objekte meistens funktionsfähig Objekte, aber auch Metadaten aus den Funktionsobjekten (deren Namen, Dokumentzeichenfolgen und Definitionsreihenfolge) sind Teil der Eingabe. Es ist kein so gutes Beispiel für die Verwendung von
globals()
. Außerdem wird es von der 'Konfiguration' importiert - letztere ist ein normales Python-Skript - und nicht umgekehrt.Ich habe 'deklaratives Python' für einige Projekte verwendet, an denen ich gearbeitet habe, und hatte Gelegenheit,
globals()
Konfigurationen für diese zu schreiben. Man könnte sicherlich argumentieren, dass dies auf eine Schwäche in der Art und Weise zurückzuführen ist, wie die Konfigurationssprache entworfen wurde. Gebrauch vonglobals()
auf diese Weise führt nicht zu sehr klaren Ergebnissen. Nur Ergebnisse, die möglicherweise einfacher zu pflegen sind als ein Dutzend nahezu identischer Aussagen.Sie können es auch verwenden, um Variablen innerhalb der Konfigurationsdatei entsprechend ihren Namen eine Bedeutung zu geben:
# All variables above here starting with Foo_k_ are collected # in Bar_klist # foo_k = [ v for k,v in globals().items() if k.startswith('Foo_k_')] Bar_klist = BarDef( foo_k , method = "kset")
Diese Methode kann für jedes Python-Modul nützlich sein , das viele Tabellen und Strukturen definiert, um das Hinzufügen von Elementen zu den Daten zu vereinfachen, ohne dass auch die Referenzen gepflegt werden müssen.
quelle
Es kann auch verwendet werden, um eine Instanz der Klasse 'classname' aus einer Zeichenfolge abzurufen:
class C: def __init__(self, x): self.x = x print('Added new instance, x:', self.x) def call(str): obj = globals()[str](4) return obj c = call('C') print(c.x)
quelle
Es kann nützlich sein, wenn Sie das gerade erstellte Modul importieren möchten:
a.py.
[...] def buildModule(): [...code to build module...] return __import__("somemodule") [...]
b.py.
from a import buildModule def setup(): globals()["somemodule"] = buildModule()
quelle
Nicht wirklich. Globale Variablen, über die Python wirklich verfügt, sind Variablen mit Modulbereich.
# a.py print(globals()) import b b.tt()
# b.py def tt(): print(globals())
laufen
python a.py
, mindestens zwei Ausgabe vonglobals()['__name__']
ist unterschiedlich.Code hier in cpython auf Github zeigt es.
quelle