globale Variablen und Module

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Holger Chapman
User
Beiträge: 35
Registriert: Samstag 12. Juli 2014, 01:59

Hallo,

ich schreibe ein Programm, bei dem ich in allen möglichen Funktionen auf ein (sehr umfangreiches) Dictionary zugreife. Das Dictionary soll eine globale Variable sein. Das funktioniert erstmal problemlos (wenn ich alles richtig verstanden habe, kann ich "mutable" Dateitypen wie Listen und Dictionaries, die im Hauptprogramm angelegt wurden, einfach global benutzen):

Code: Alles auswählen

def newDictEntry(newKey, newValue):
    myDict[newKey] = newValue
    
myDict = {1: 'eins', 2: 'zwei'}
newDictEntry(3, 'drei')
print(myDict)
Der Output ist:
{1: 'eins', 2: 'zwei', 3: 'drei'}

Wenn ich meine Funktion ("newDictEntry") aber als Modul in einer anderen Datei ablege, funktioniert es nicht mehr:

Code: Alles auswählen

from myFunction import *
    
myDict = {1: 'eins', 2: 'zwei'}
newDictEntry(3, 'drei')
print(myDict)

Code: Alles auswählen

def newDictEntry(newKey, newValue):
    myDict[newKey] = newValue
Der Output ist:
Traceback (most recent call last):
File "/home/holger/eclipse-workspace/test/main.py", line 4, in <module>
newDictEntry(3, 'drei')
File "/home/holger/eclipse-workspace/test/myFunction.py", line 2, in newDictEntry
myDict[newKey] = newValue
NameError: name 'myDict' is not defined

Kann ich mit globalen Dictionaries arbeiten und trotzdem Funktionen, die auf diese Dictionaries zugreifen sollen, als Module in anderen Dateien ablegen? - Und wenn ja: wie?

Vielen Dank!


Holger
nezzcarth
User
Beiträge: 1753
Registriert: Samstag 16. April 2011, 12:47

Die importierte Funktion greift auf ein Dictionary in ihrem Namenspace zu (das es nicht gibt), nicht auf ein vermeintlich "modulübergreifend globales". Die Funktion kann das Dictionary des aufrufenden Moduls nicht sehen. Wenn überhaupt, dann müsstest du es als Parameter übergeben. An sich sind Funktionen, die auf eine globale Datenstruktur zugreifen aber eher seltsam. Dafür gibt es eigentlich Klassen, die für solche Kapselungen gedacht sind. Weiterhin sollte. Funktionen und normale Variablennamen per PEP8 keinen camelCase verwenden.
Sirius3
User
Beiträge: 18265
Registriert: Sonntag 21. Oktober 2012, 17:20

@Holger Chapman: das ist einer der Gründe, warum man keine globalen Variablen benutzen sollte. Warum willst Du das unbedingt? Was willst Du eigentlich erreichen?
Holger Chapman
User
Beiträge: 35
Registriert: Samstag 12. Juli 2014, 01:59

Hallo nezzcarth,
nezzcarth hat geschrieben: Montag 29. Oktober 2018, 12:55 Die importierte Funktion greift auf ein Dictionary in ihrem Namenspace zu (das es nicht gibt), nicht auf ein vermeintlich "modulübergreifend globales".
Okay. Gibt es denn sowas wie "modulübergreifende globale Dictionaries", oder muss ich mir diese Idee aus dem Kopf schlagen?
nezzcarth hat geschrieben: Montag 29. Oktober 2018, 12:55 Die Funktion kann das Dictionary des aufrufenden Moduls nicht sehen. Wenn überhaupt, dann müsstest du es als Parameter übergeben.
Ist das aus Performance-Gründen sinnvoll? Wird das (umfangreiche) Dictionary dann jedesmal kopiert, oder wird nur ein zusätzlicher Zeiger auf das Dictionary erzeugt?
nezzcarth hat geschrieben: Montag 29. Oktober 2018, 12:55 Weiterhin sollte. Funktionen und normale Variablennamen per PEP8 keinen camelCase verwenden.
Ah. https://www.python.org/dev/peps/pep-000 ... able-names. Das wusste ich noch nicht.

Schönen Gruß


Holger
Holger Chapman
User
Beiträge: 35
Registriert: Samstag 12. Juli 2014, 01:59

Hallo Sirius3,
Sirius3 hat geschrieben: Montag 29. Oktober 2018, 13:33 das ist einer der Gründe, warum man keine globalen Variablen benutzen sollte. Warum willst Du das unbedingt? Was willst Du eigentlich erreichen?
Mein Programm soll alle Dateien auf meiner Festplatte indizieren und anschließend verschiedene Aktionen ausführen, z. B. bestimmte Ordnerhierarchien löschen.
Da wäre es sinnvoll, wenn z. B. eine Funktion "Ordner inkl. Inhalt löschen" direkt auf das Dictionary zugreifen kann, in dem die Verzeichnisstruktur abgebildet ist.
Und es wäre sinnvoll, wenn z. B. eine Funktion "Datei löschen" auch veranlassen könnte, dass die Gesamtgröße aller übergeordneten Verzeichnisse jeweils um die Dateigröße reduziert wird.

Bisher habe ich die Informationen in (global benutzbaren) Dictionaries abgelegt. Das hat so lange wunderbar funktioniert, bis ich einige Funktionen in getrennte Dateien (Module) auslagern wollte.

Vielleicht wäre es besser, wenn ich die Informationen nicht in Dictionaries ablege, sondern in einer Datenbank (SQLite)? Kann ich dann aus Modulen heraus auf die Datenbank zugreifen?
... oder ich muss doch objektorientiert arbeiten. Davor habe ich mich bisher gedrückt ...

Schönen Gruß


Holger
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Holger Chapman hat geschrieben: Montag 29. Oktober 2018, 14:04
nezzcarth hat geschrieben: Montag 29. Oktober 2018, 12:55 Die Funktion kann das Dictionary des aufrufenden Moduls nicht sehen. Wenn überhaupt, dann müsstest du es als Parameter übergeben.
Ist das aus Performance-Gründen sinnvoll? Wird das (umfangreiche) Dictionary dann jedesmal kopiert, oder wird nur ein zusätzlicher Zeiger auf das Dictionary erzeugt?
Parameter werden in Python immer per Referenz übergeben. Alle Funktionen greifen dann also auf das selbe Objekt zu.
Sirius3
User
Beiträge: 18265
Registriert: Sonntag 21. Oktober 2012, 17:20

@Holger Chapman: wenn es Funktionen gibt, die auf dem Wörterbuch arbeiten, drängen sich Klassen statt Wörterbücher geradezu auf. Von der Performance sind globale Wörterbucher im nicht messbaren Bereich langsamer als lokale Variablen.
Wenn Du die Information über das Programmende hinaus behalten willst, kannst Du über eine Datenbank nachdenken. Ansonsten sollte die Klassenstruktur so allgemein gehalten sein, dass es später von der Bedienung keinen Unterschied macht, ob Du mit einer Datenbank oder mit Wörterbüchern oder irgend etwas anderes arbeitest.
Antworten