Variablen von Modul zu Modul übertragen.

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
anonym9

Hallo liebes Forum.

Ich bin noch nicht sehr weit in Python und habe deshalb eine Verständnisfrage zu (globalen) Variablen. Gerne würde ich wissen ob ich eine Variable so nutzen kann, dass sie in allen Modulen verfügbar ist. Die Frage wird oft gestellt und offenbar auch viel per Suchmaschine gesucht, aber die Standardlösung (https://discuss.python.org/t/global-var ... ules/16833) greift nicht in allen Fällen.

Angenommen ich haben drei Dateien:

Haupt.py – hier wird Funk1() aus der Datei Funktion 1.py ausgeführt – eingebunden über

Code: Alles auswählen

"import Funktion1
(...)
funktion1.Funk1()"
Funktion1.py
Funk1() erzeugt (bspw. durch Webscraping) die variable X.

Funktion2.py
Funk2() soll mit Variable X weiterarbeiten, kann jedoch nicht auf X zugreifen. Wären alle Funktionen in der selben Datei (und wäre X als global definiert) wäre es kein Problem. In verschiedenen Modulen ist dies jedoch offenbar nicht möglich.
Die üblichen Lösungsvorschläge schlagen vor X in einem weiteren Modul zu speichern (z.B. config.py) und dann für alle anderen Dateien (Haupt.py, Funk1.py, usw.) per import verfügbar zu machen (import config (...) config.X). So wie ich das aber sehe, trifft dies nur auf Variablen zu, die schon vor Programmbeginn bekannt sind. Wenn ich richtig informiert bin, dann kann ich doch keine Variable die ich während der Laufzeit definiere in eine Variable einer externen .py Datei schreiben, oder?

Mein Workaround war bisher solche Variablen in eine txt zu schreiben und sie dann vom jeweiligen Modul wieder daraus laden zu lassen. Ich habe aber den Eindruck, dass das nicht die optimale und seriöse Art ist das Problem zu lösen.

Könnt ihr mir helfen? (Und bitte seid nachsichtig, ich lerne erst seit zwei Wochen).

Liebe Grüße!
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kkci: Die Standardlösung funktioniert immer und die ist so etwas Unsinniges gar nicht zu machen. Man überträgt keine Variablen ”von Modul zu Modul” und man benutzt auch innerhalb eines Moduls keine globalen Variablen. Wenn eine Funktion ein Ergebnis produziert, dann gibt sie dieses Ergebnis zurück. Und alles was Funktionen und Methoden ausser Konstanten benötigen, bekommen sie als Argumen(e) übergeben. Module, also wo welche Funktion/Methode definiert ist, spielen dabei überhaupt gar keine Rolle.

Im Hauptprogramm in einer Funktion (oder Methode):

Code: Alles auswählen

    x = function_a()
    function_b(x)
Und dabei ist vollkommen egal wo die beiden Funktionen definiert wurden. Ob im gleichen Modul, im Modul wo sie aufgerufen werden, oder in zwei unterschiedlichen Modulen — Module spielen bei der Übergabe und Rückgabe von Werten keinerlei Rolle.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
anonym9

Mir fällt es gerade noch nicht so leicht zu verstehen, wie du das meinst (mind you, ich hab wirklich noch wenig Ahnung von Python). Ich glaube es könnte auch sein, dass ich mich unverständlich ausgedrückt habe.

Ich stelle mal ein paar Nachfragen, falls du dich erbarmen kannst würde ich mich freuen :D

Es geht mir nicht darum, dass ich der Funktion keine Variablen übergeben möchte (das tue ich ja), sondern dass ich den Output der Funktion (sorry wenn das das falsche Wort ist) einer anderen Funktion (in einem anderen Modul) als Parameter übergeben möchte. Das funktioniert aber nicht, wie ich es verstanden habe. Da würde ich gerne meinen Denkfehler erklärt bekommen.

Ist es falsch Funktionen auf verschiedene Module zu verteilen? (Gesetzt den Fall, dass man sie vielleicht wieder verwendet und dann nicht copy-and-paste mäßig überall eventuelle fehler verbessern muss?)


Du schreibst:
"Die Standardlösung funktioniert immer und die ist so etwas Unsinniges gar nicht zu machen. Man überträgt keine Variablen ”von Modul zu Modul” und man benutzt auch innerhalb eines Moduls keine globalen Variablen. "

Ich hab den Satz jetzt ein paar mal gelesen, aber ich verstehe es wirklich nicht (stelle mich nicht mit Absicht blöd an, versprochen). Du meinst mein vorgehen ist unsinnig und es gibt einen besseren weg? Oder ist das ganze vorhaben für dich unverständlich?

Den zweiten Satz verstehe ich besser, also dass man innerhalb von modulen keine globalen Variablen setzt. Ich denke das wird sich auch beim lernen noch weiter erschließen. Was ich allerdings nicht verstehe ist, warum man keine Variablen von Modul zu Modul überträgt. Habe ich mich da falsch ausgedrückt? Ich meinte von funktionX zu FunktionY, die sich ggf. in 2 verschiedenen Dateien befinden (dachte das nennt man dann Modul). Ist das wirklich eine schlechte Idee? Bin gerade super verwirrt.

Aber danke für deine Antwort!! :)
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Der Input einer Funktion sind ihre Argumente, und der Output ist der Rückgabewert.
Wie das geht, hat __blackjack__ in seinem Codebeispiel gezeigt.
Du hast eine funktion_a und eine funktion_b, der Output `x` von funktion_a wird an funktion_b "übergeben":

Code: Alles auswählen

x = function_a()
function_b(x)
Dabei kann function_a in dem einen Modul sein, und function_b in einem ganz anderen, völlig egal.
Hier noch ein konkreteres Beispiel, wo funktion_a `input` heißt und funktion_b `print`:

Code: Alles auswählen

name = input("Dein Name: ")
print("Hallo", name)
anonym9

Ok, ich glaub ich stehe ein bisschen zu sehr auf dem Schlauch um das zu verstehen was du meinst.

Aber ein weiterer Blick in die Dokumentation (https://docs.python.org/3/faq/programmi ... ss-modules) hat geholfen.

Thema erledigt. Der Weg wie er im Handbuch ist funktioniert natürlich. Ein Tippfehler hat eine Fehlermeldung produziert die ich falsch interpretiert hatte.
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kkci: Argh! Vergiss das bitte gleich wieder. Das ist Unsinn. So macht man das nicht. Das so eine Scheisse in der Python-Dokumentation steht ist ziemlich übel. 😱
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
anonym9

Also ich kann mir ja vorstellen, dass bestimmte Anfängerfehler/Schreibweisen nerven können und viele Fragestellungen für nicht-Neulinge lachhaft/offensichtlich scheinen... aber ein bisschen mehr Input (Warum ist so etwas übel? Was ist das konkrete Problem? und wie ist die korrekte Lösung) würde dem Thread sicherlich gut tun. Auch im Hinblick auf zukünftige User, die den Thread vielleicht per Suchmaschiene finden und auch nur die Dokumentation lesen.
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kkci: Man verwendet keine globalen Variablen. Das ist nicht neu, die Gründe finden sich tausendfach im Netz, Anfänger verstehen die Gründe nicht, und sollten einfach glauben das es welche gibt und das man keine globalen Variablen verwendet. Und die Lösung wurde bereits genannt. Mit Beispielen die Lösung ist supereinfach. Das sind Grundlagen von Funktionen, dass die Argumente und Rückgabewerte haben. Wenn Du das nicht verstanden hast, dann hast Du Funktionen nicht verstanden. Das ist ein Thema das man verstanden haben sollte *bevor* man anfängt sich mit mehreren Modulen zu beschäftigen. Denn den eigenen Code auf Module aufzuteilen kommt ja in der Regel erst wenn man so viel Code hat, das es Sinn macht den auf Module aufzuteilen.

Wenn man mehrere Module hat, sollte man eigentlich auch gleich Packages lernen/verstehen, denn mehr als ein Modul sollte in einem Package stecken, damit man auf oberster Ebene nur einen Namen hat der in Konkurrenz zu allen anderen Packages und Modulen steht. Da lauern nämlich auch Probleme, wenn man dann irgendwann Module hat, mit gleichen Namen wie Module die man installieren und benutzen möchte, oder die es mit dem Namen auch in der Standardbibliothek gibt. Oder in Zukunft geben wird.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
anonym9

Huch, spannender Umgangston. Ich such mir mal besser ein Forum, das besser meinem Gemüt entspricht. Danke trotzdem für deine Zeit.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@kkci: wenn Du mein Beispiel nicht verstehst, vielleicht kannst Du mal Dein Problem hier ganz konkret mit Code beschreiben. Darauf aufbauend wird die Antwort vielleicht klarer.
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kkci: Sorry, aber es ist halt kompletter Unsinn das so zu machen. Du hast ja sicher schon Funktionen verwendet, aus anderen Modulen. Nirgends wird das so gemacht wie Du das da vorhast. Das ist doch auch super-umständlich und schwer verständlich im Gegensatz zum normalen, vorgesehenen Vorgehen. Stell Dir mal vor alle Funktionen würden das so machen. Das geht doch gar nicht, weil man dann zu jeder Funktion noch wissen müsste unter welchen Namen man die Eingangswerte in welchem Modul ablegen muss, bevor man die aufruft, und unter welchem/welchen Namen das oder die Ergebnisse in welchem Modul nach dem Aufruf existieren. Und alle Namen für Eingangswerte und Ergebnisse in den jeweiligen Modulen müssen unterschiedlich sein, weil es sonst ja passieren kann, das Werte von anderen Aufrufen überschrieben werden. Und selbst dann bekommt man noch Probleme wenn man eine Funktion mehr als einmal aufrufen will, um die Ergebnisse irgendwie miteinander zu verrechnen. Man müsste immer nach jedem Aufruf und vor dem nächsten die Ergebnisse in lokale Variablen sichern, weil man ja nicht weiss was eine Funktion die man aufruft, selbst noch so alles aufruft.

Rekursion oder mehrere Threads ginge so gar nicht.

Stell Dir mal vor Funktionen würden tatsächlich so funktionieren. Dann würde die Eingabe von zwei Zahlen und die Ausgabe der Summe so aussehen:

Code: Alles auswählen

import builtins


def main():
    builtins.prompt = "Eingabe erste Zahl: "
    input()
    builtins.value = builtins.input_result
    int()
    first_value = builtins.int_result

    builtins.prompt = "Eingabe zweite Zahl: "
    input()
    builtins.value = builtins.input_result
    int()
    second_value = builtins.int_result

    builtins.value = "Summe:"
    print()
    builtins.value = first_value + second_value
    print()


if __name__ == "__main__":
    main()
Statt einfach:

Code: Alles auswählen

def main():
    first_value = int(input("Eingabe erste Zahl: "))
    second_value = int(input("Eingabe zweite Zahl: "))
    print("Summe:")
    print(first_value + second_value)


if __name__ == "__main__":
    main()
Man könnte dann sogar ``print("Summe:", first_value + second_value)`` in einem Aufruf machen. Wie würde man denn variable Anzahlen von Argumenten über globale Variablen lösen? Und optionale Argumente? Von denen `int()` und `print()` ja auch welche haben‽
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten