Seite 1 von 1

globale Variablen und Module

Verfasst: Montag 29. Oktober 2018, 12:32
von Holger Chapman
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

Re: globale Variablen und Module

Verfasst: Montag 29. Oktober 2018, 12:55
von nezzcarth
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.

Re: globale Variablen und Module

Verfasst: Montag 29. Oktober 2018, 13:33
von Sirius3
@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?

Re: globale Variablen und Module

Verfasst: Montag 29. Oktober 2018, 14:04
von Holger Chapman
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

Re: globale Variablen und Module

Verfasst: Montag 29. Oktober 2018, 14:04
von Holger Chapman
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

Re: globale Variablen und Module

Verfasst: Montag 29. Oktober 2018, 14:27
von snafu
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.

Re: globale Variablen und Module

Verfasst: Montag 29. Oktober 2018, 14:46
von Sirius3
@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.