Die __debug__
Variable ist teilweise praktisch, weil sie jedes Modul betrifft. Wie würde ich es tun, wenn ich eine andere Variable erstellen möchte, die auf die gleiche Weise funktioniert?
Die Variable (seien wir originell und nennen sie 'foo') muss nicht wirklich global sein, in dem Sinne, dass wenn ich foo in einem Modul ändere, sie in anderen Modulen aktualisiert wird. Es wäre in Ordnung, wenn ich vor dem Importieren anderer Module foo setzen könnte und sie dann den gleichen Wert dafür sehen würden.
hasattr(__builtin__, "foo")
.Wenn Sie eine globale modulübergreifende Variable benötigen, reicht möglicherweise nur eine einfache globale Variable auf Modulebene aus.
a.py:
b.py:
c.py:
Prüfung:
Beispiel aus der Praxis : Djangos global_settings.py (obwohl in Django-Apps Einstellungen durch Importieren des Objekts verwendet werden
django.conf.settings
).quelle
a.py
enthältmain()
? Ist das wichtig?if __name__=="__main__"
Guard darin, um zu vermeiden, dass beim Import unerwarteter Code ausgeführt wird.id()
, um die Identität zu überprüfen)Definieren Sie ein Modul (nennen Sie es "globalbaz") und definieren Sie die darin enthaltenen Variablen. Alle Module, die dieses "Pseudoglobal" verwenden, sollten das "globalbaz" -Modul importieren und mit "globalbaz.var_name" darauf verweisen.
Dies funktioniert unabhängig vom Ort der Änderung. Sie können die Variable vor oder nach dem Import ändern. Das importierte Modul verwendet den neuesten Wert. (Ich habe dies in einem Spielzeugbeispiel getestet)
Zur Verdeutlichung sieht globalbaz.py folgendermaßen aus:
quelle
Ich glaube, dass es viele Umstände gibt, unter denen es sinnvoll ist, und es vereinfacht die Programmierung, einige globale Elemente zu haben, die über mehrere (eng gekoppelte) Module hinweg bekannt sind. In diesem Sinne möchte ich ein wenig auf die Idee eingehen, ein Modul von Globals zu haben, das von den Modulen importiert wird, die auf sie verweisen müssen.
Wenn es nur ein solches Modul gibt, nenne ich es "g". Darin weise ich jeder Variablen, die ich als global behandeln möchte, Standardwerte zu. In jedem Modul, das eines von ihnen verwendet, verwende ich nicht "from g import var", da dies nur zu einer lokalen Variablen führt, die nur zum Zeitpunkt des Imports von g initialisiert wird. Ich mache die meisten Referenzen in der Form g.var und dem "g". dient als ständige Erinnerung daran, dass es sich um eine Variable handelt, auf die möglicherweise andere Module zugreifen können.
Wenn der Wert einer solchen globalen Variablen in einer Funktion eines Moduls häufig verwendet werden soll, kann diese Funktion eine lokale Kopie erstellen: var = g.var. Es ist jedoch wichtig zu wissen, dass Zuweisungen an var lokal sind und die globale g.var nicht aktualisiert werden kann, ohne g.var in einer Zuweisung explizit zu referenzieren.
Beachten Sie, dass Sie auch mehrere solcher globalen Module haben können, die von verschiedenen Teilmengen Ihrer Module gemeinsam genutzt werden, um die Kontrolle zu behalten. Der Grund, warum ich Kurznamen für meine globalen Module verwende, besteht darin, zu vermeiden, dass der Code zu stark mit Vorkommen überladen wird. Mit nur wenig Erfahrung werden sie mit nur 1 oder 2 Zeichen mnemonisch genug.
Es ist immer noch möglich, eine Zuordnung beispielsweise zu gx vorzunehmen, wenn x nicht bereits in g definiert wurde, und ein anderes Modul kann dann auf gx zugreifen. Obwohl der Interpreter dies zulässt, ist dieser Ansatz nicht so transparent, und ich vermeide es es. Es besteht weiterhin die Möglichkeit, versehentlich eine neue Variable in g aufgrund eines Tippfehlers im Variablennamen für eine Zuweisung zu erstellen. Manchmal ist eine Untersuchung von dir (g) nützlich, um Überraschungsnamen zu entdecken, die durch einen solchen Unfall entstanden sein könnten.
quelle
Sie können die Globals eines Moduls an ein anderes übergeben:
In Modul A:
In Modul B:
quelle
Globale Variablen sind normalerweise eine schlechte Idee, aber Sie können dies tun, indem Sie Folgendes zuweisen
__builtins__
:Außerdem sind Module selbst Variablen, auf die Sie von jedem Modul aus zugreifen können. Wenn Sie also ein Modul mit dem Namen definieren
my_globals.py
:Dann können Sie das auch von überall aus verwenden:
Die Verwendung von Modulen anstelle von Änderungen
__builtins__
ist im Allgemeinen eine sauberere Methode, um solche Globals zu erstellen.quelle
__builtins__
ist eine CPython-Besonderheit, Sie sollten sie wirklich nicht verwenden - besser verwenden__builtin__
(oderbuiltins
in Python3), wie die akzeptierte Antwort zeigtSie können dies bereits mit Variablen auf Modulebene tun. Module sind gleich, unabhängig davon, aus welchem Modul sie importiert werden. Sie können die Variable also zu einer Variablen auf Modulebene in einem beliebigen Modul machen, in das sie sinnvoll eingefügt werden soll, und von anderen Modulen aus darauf zugreifen oder ihr zuweisen. Es ist besser, eine Funktion aufzurufen, um den Wert der Variablen festzulegen, oder sie zu einer Eigenschaft eines Singleton-Objekts zu machen. Auf diese Weise können Sie, wenn Sie beim Ändern der Variablen Code ausführen müssen, dies tun, ohne die externe Schnittstelle Ihres Moduls zu beschädigen.
Es ist normalerweise keine großartige Möglichkeit, Dinge zu tun - mit Globals selten -, aber ich denke, dies ist die sauberste Art, dies zu tun.
quelle
Ich wollte eine Antwort posten, dass es einen Fall gibt, in dem die Variable nicht gefunden wird.
Zyklische Importe können das Modulverhalten beeinträchtigen.
Beispielsweise:
first.py
second.py
main.py.
In diesem Beispiel sollte es offensichtlich sein, aber in einer großen Codebasis kann dies wirklich verwirrend sein.
quelle
Das klingt nach einer Änderung des
__builtin__
Namensraums. Es zu tun:Verwenden Sie das nicht
__builtins__
direkt (beachten Sie die zusätzlichen "s") - anscheinend kann dies ein Wörterbuch oder ein Modul sein. Dank an ΤΖΩΤΖΙΟΥ für diesen Hinweis finden Sie hier mehr .Jetzt
foo
ist überall verfügbar.Ich empfehle dies im Allgemeinen nicht, aber die Verwendung liegt beim Programmierer.
Die Zuweisung muss wie oben erfolgen. Durch einfaches Einstellen
foo = 'some-other-value'
wird es nur im aktuellen Namespace festgelegt.quelle
Ich benutze dies für ein paar eingebaute primitive Funktionen, die mir wirklich fehlten. Ein Beispiel ist eine Suchfunktion, die dieselbe Verwendungssemantik wie Filter, Map, Reduce hat.
Sobald dies ausgeführt wird (z. B. durch Importieren in der Nähe Ihres Einstiegspunkts), können alle Ihre Module find () verwenden, als ob es offensichtlich eingebaut wäre.
Hinweis: Sie können dies natürlich mit einem Filter und einer anderen Zeile tun, um die Länge auf Null zu testen, oder mit einer Verringerung einer seltsamen Zeile, aber ich fand es immer seltsam.
quelle
Mit einem Wörterbuch konnte ich modulübergreifende modifizierbare (oder veränderbare ) Variablen erzielen :
Beim Start
test_wait_app_up_fail
beträgt die tatsächliche Zeitüberschreitungsdauer 3 Sekunden.quelle
Ich habe mich gefragt, ob es möglich ist, einige der Nachteile der Verwendung globaler Variablen (siehe z. B. http://wiki.c2.com/?GlobalVariablesAreBad ) zu vermeiden, indem ein Klassennamensraum anstelle eines globalen / Modul-Namespace verwendet wird, um Werte von Variablen zu übergeben . Der folgende Code zeigt an, dass die beiden Methoden im Wesentlichen identisch sind. Es ist ein kleiner Vorteil, Klassennamensräume zu verwenden, wie unten erläutert.
Die folgenden Codefragmente zeigen auch, dass Attribute oder Variablen sowohl in globalen / Modul-Namespaces als auch in Klassennamensräumen dynamisch erstellt und gelöscht werden können.
wall.py
Ich nenne dieses Modul "Wand", da es zum Abprallen von Variablen verwendet wird. Es dient als Leerzeichen zum vorübergehenden Definieren globaler Variablen und klassenweiter Attribute der leeren Klasse 'Router'.
source.py
Dieses Modul importiert wall und definiert eine einzelne Funktion,
sourcefn
die eine Nachricht definiert und über zwei verschiedene Mechanismen ausgibt, einen über globale und einen über die Router-Funktion. Beachten Sie, dass die Variablenwall.msg
undwall.router.message
hier zum ersten Mal in ihren jeweiligen Namespaces definiert werden.dest.py.
Dieses Modul definiert eine Funktion,
destfn
die die zwei verschiedenen Mechanismen verwendet, um die von der Quelle ausgegebenen Nachrichten zu empfangen. Dies ermöglicht möglicherweise, dass die Variable 'msg' nicht vorhanden ist.destfn
löscht auch die Variablen, sobald sie angezeigt wurden.main.py.
Dieses Modul ruft die zuvor definierten Funktionen nacheinander auf. Nach dem ersten Aufruf
dest.destfn
der Variablenwall.msg
undwall.router.msg
nicht mehr vorhanden.Die Ausgabe des Programms lautet:
global: Hallo Welt!
Router: Hallo Welt!
global: keine Nachricht
Router: keine Nachricht
Die obigen Codefragmente zeigen, dass die Mechanismen module / global und class / class variable im Wesentlichen identisch sind.
Wenn viele Variablen gemeinsam genutzt werden sollen, kann die Namespace-Verschmutzung entweder mithilfe mehrerer Wandmodule, z. B. Wand1, Wand2 usw., oder durch Definieren mehrerer Routertypklassen in einer einzigen Datei verwaltet werden. Letzteres ist etwas aufgeräumter und stellt daher möglicherweise einen geringfügigen Vorteil für die Verwendung des Mechanismus mit Klassenvariablen dar.
quelle