Globale Variablen in Klassen

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
stonie69
User
Beiträge: 24
Registriert: Dienstag 11. Juni 2024, 17:56

Hi

ich möchte eine Globale Variable in einer Klasse deklarieren. Habe hier und anderswo gesucht und bin lediglich auf diese Variante gestoßen

Code: Alles auswählen

class TestGlobal():

    def set_var(self, wert):
        global varTest
        varTest = wert

    def get_var(self):
        return varTest

c = TestGlobal()
c.set_var(45)
wert = c.get_var()

print(wert)


aber geht das in Phyton nicht einfacher ?

Warum geht das nicht:

Code: Alles auswählen

global varTest
class TestGlobal():
    def Test(self, Wert):
        varTest = Wert
        print(varTest)

c = TestGlobal()
c.Test(45)
print(c.varTest)
Ja dumme Frage es geht nicht aber ist der Ansatz oben wirklich richtig ?
Benutzeravatar
kbr
User
Beiträge: 1504
Registriert: Mittwoch 15. Oktober 2008, 09:27

Eine im globalen Namespace angelegt Variable ist automatisch global, daher brauchst du sie, wie im zweiten Beispiel, nicht noch einmal als solche deklarieren. In dem Namespace hingegen, indem sie später auch schreibend verwendet werden soll, ist diese Deklarierung erforderlich, sonst würde eine gleichnamige lokale Variable angelegt werden. Daher ist das erste Beispiel richtig. Jedenfalls syntaktisch – ansonsten ist es sinnfrei. Die Verwendung von "global" ist in den meisten Fällen zudem eine eher schlechte Idee – Programme können dadurch fehleranfällig werden und auch die Fehlersuche und deren Beseitigung kann sich schwierig gestalten.
Benutzeravatar
sparrow
User
Beiträge: 4527
Registriert: Freitag 17. April 2009, 10:28

Du bringst hier ein paar Dinge durcheinander, die du erst einmal entwirren musst.

Zuerst einmal: Globale Variablen möchte man in seinem Programm nicht haben. Sie sind auch völlig unnötig. Vergiss, dass es global gibt. Wenn du an einen Punkt kommst, an dem du das verwenden musst oder über globale Variablen nachdenkst, machst du grundsätzlich etwas verkehrt.

Es gilt: Auf Modulebene - also nicht eingerückt - gehören ausschließlich: der/die/das shebank, Importe und die Definition von Klassen, Funktionen und Konstanten (Konstanten in heißt hier: Werte die sich während der Laufzeit niemals ändern). Und natürlich die Importweiche mit if __name__ == __main__: [...].

Ich empfehle dringend, das offizielle Python-Tutorial durchzuarbeiten. Denn da wird ziemlich gut erklärt, wie Klassen und Objektorientierte Programmierung in Python funktioniert.
Denn du willst gar keine globale Variable. In deinen Beispielen willst du ja eher Eigenschaften in der Instanz einer Klasse setzen.
Und diese pseudo Setter und Getter sind in Python auch völlig überflüssig.

Code: Alles auswählen

class Person():
    def __init__(self, name=""):
        self.name = name

def main():
    person = Person("stonie")
    print(person.name)
    person.name = "Nobody"
    print(person.name)

if __name__ == "__main__":
    main()
Wobei man Klassen nicht als Wertspeicher benutzen sollte. Da gibt es in Python schönere Methoden.
Allerdings entspricht das hier in etwa deinen Beispielen.
stonie69
User
Beiträge: 24
Registriert: Dienstag 11. Juni 2024, 17:56

@sparrow.

Vielen Dank für deine Ausführliche Darstellung der Sache.
Ja du hast recht ich muss noch viel lesen. Möchte aber erstmal von einem alten Programm das in VB und VBA (Access) geschrieben ist ein paar grundlegende Dinge ausprobieren und bin von daher sehr dankbar für solche Darstellungen.

Kannst du mir noch eine Tipp geben welche Methode du verwenden würdest?

@kbr
Auch dir vielen Dank für deine Sichtweise die sich mit @sparrow deckt. Danke
Benutzeravatar
__blackjack__
User
Beiträge: 14002
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@stonie69: Was meinst Du mit „welche Methode“? Was ist denn das Problem das Du lösen möchtest?

Ich würde das mit dem Wertspeicher noch mal konkretisieren wollen: Ich nehme an sparrow meinte hier speziell eine Klasse für nur einen einzigen Wert zu verwenden. Dafür gibt es Anwendungen, zum Beispiel um ein Objekt in einem anderen zu verpacken, das eine andere oder speziellere API zur Verfügung stellt.

Datenklassen, also Klassen die erst einmal nur verschiedene zusammengehörende Werte zu einem Objekt zusammenfassen, und sonst kein weiteres Verhalten haben, sind in der Regel okay. Oft finden sich bei solchen Objekten dann im Laufe der Entwicklung auch Methoden die Sinn machen.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
stonie69
User
Beiträge: 24
Registriert: Dienstag 11. Juni 2024, 17:56

@__blackjack__

Ich habe mich von den globalen Variablen in die irre führen lassen, weil ich mich zu sehr drauf versteift habe, dass ich diese brauche aber das funktioniert so wie oben beschrieben genau so wie ich mir das vorgestellt habe. Funktion- / Klassenübergreifend und die Möglichkeit die Variable z.B. "name" mit in den "def __init__(self, name=""):" mit auf zu nehmen hat mir genau das gezeigt, das ich so auch angeben kann was für Variablen möglich sind.

Habe meine Klasse in Datei X (Nachname habe ich bewußt weg gelassen)

Code: Alles auswählen

class Person():
    def __init__(self, Vorname=""):
        self.Vorname = Vorname
        self.Nachname = None
und den Aufruf in einer anderen Datei "Funktion"

Code: Alles auswählen

from test import Person

def main():
from test import Person

def main():
    p1 = Person(Vorname="Michael")
    p1.Nachname = "Müller"

    p2 = Person()
    p2.Vorname = "Karsten"
    p2.Nachname = "Schulz"

    print(p1.Nachname + " " + p1.Vorname)
    print(p2.Nachname + " " + p2.Vorname)

if __name__ == "__main__":
    main()
Prima ich bin zufrieden gerade mit dem Hinweis / Möglichkeit "def __init__(self, Vorname=""):"

Aber habe schon wieder eine neue Frage die ich neu reinstelle. Jetzt hänge ich am erstellen einer Windows - Exe :oops:

Danke euch allen für die super Unterstützung
Gutes Nächtle
Benutzeravatar
__blackjack__
User
Beiträge: 14002
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@stonie69: Das ist als Beispiel aber nicht wirklich gut, denn normalerweise erstellt man Objekte erst wenn man die Werte dafür beisammen hat. Nach dem die `__init__()` durch ist, sollte ein Objekt normalerweise komplett und in einem benutzbaren Zustand sein.

Zeichenketten und Werte mit ``+`` zusammenstückeln ist eher BASIC als Python. Im Konkreten Fall könnte man die beiden Werte an `print()` auch einzeln übergeben, denn das Leerzeichen dazwischen setzt `print()` ja schon, oder man verwendet ein f-Zeichenkettenliteral um die Zeichenkette zu erstellen. Und da dort zwei mal das gleiche stehen würde, könnte man sich auch überlegen das zur Zeichenkettendarstellung von `Person`-Objekten zu machen.

Code: Alles auswählen

class Person:
    def __init__(self, vorname, nachname):
        self.vorname = vorname
        self.nachname = nachname
    
    def __str__(self):
        return f"{self.nachname} {self.vorname}"


def main():
    michael = Person("Michael", "Müller")
    karsten = Person("Karsten", "Schulz")
    print(michael)
    print(karsten)


if __name__ == "__main__":
    main()
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
stonie69
User
Beiträge: 24
Registriert: Dienstag 11. Juni 2024, 17:56

@__blackjack__:

Ja du hast recht man kann einiges besser machen und ich lerne aktuell jeden Tag was neues und durch diese kleinen Codschnipsel schon wieder etwas :-)

Aber jetzt ist schluß für Heute und morgen geht es auf's Motorrad :-)

Gruß und gutes Nächtle
Antworten