Wertübergabe zwischen Objekten verschiedener 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
Mubange
User
Beiträge: 3
Registriert: Mittwoch 2. August 2023, 22:10

Moin,
ich bin neu hier, beschäftige mich schon länger mit Python, bin aber Autodidakt und mir oft nicht sicher, ob ich die besten Lösungen finde.

So auch hier. Ich habe ein kurzes Beispielprogramm geschrieben, das mein Problem aufzeigen soll und durchaus auch löst. Die Frage ist also, ob das besser / eleganter geht.

Was wollte ich machen?
Ein Objekt der Klasse Test kann über die Funktion objektAnlegen() Objekte der Klasse "dasObjekt" erstellen und übergibt ihnen einen Wert. Das erschaffene "dasobjekt"-Objek fügt nun einer Liste in dem "Test"-Objekt einen Wert hinzu, betreibt also quasi Datenaustausch mit ihm.
Sorry ich kann es leider nicht wirklich gut beschreiben, ich hoffe aber , man versteht, was ich meine. Wenn nein, hier der Code:

Code: Alles auswählen

class test():

    def __init__(self):

        self.objekte = [ ]
        self.wert = [ ]
        self.ich = self

    def objektAnlegen(self, wertObjekt):
        self.objekte += [dasObjekt(self.ich, wertObjekt)]

class dasObjekt():

    def __init__(self,erschaffendesTestObjekt, wertObjekt):

        self.erschaffendesTestObjekt = erschaffendesTestObjekt
        self.wertObjekt = wertObjekt
        self.erschaffendesTestObjekt.wert += [self.wertObjekt]



# main

testklasse = test()

testklasse.objektAnlegen(12)

print("Wert: ", testklasse.wert)

Ausgabe:

Code: Alles auswählen

Wert:  [12]
Wie gesagt, funktioniert soweit, aber irgendwie werde ich das Gefühl nicht los, dass es eine bessere Lösung geben könnte, also vor Allem mit dem "self.ich" :?
Vielen Dank für Euren Input! :)
Zuletzt geändert von Mubange am Mittwoch 2. August 2023, 22:42, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Einfach statt self.ich self - das war’s.
Mubange
User
Beiträge: 3
Registriert: Mittwoch 2. August 2023, 22:10

Na, dann war ich ja nah dran. Ich danke dir!
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Es ist komisch, dass eine Instanz eine Referenz auf eine andere Instanz übergeben bekommt und dann diese wiederum verändert. Das liegt vielleicht an einer zu großen Simplifizierung Deines Problems, aber so macht man das generell nicht.

Klassen fangen immer mit einem Großen Anfangsbuchstaben an, damit man sie als Klassen erkennen kann. Methoden und Variablen werden komplett klein geschrieben.
"Objekt" an Variablennamen anziuhängen ist wenig aussagekräftig, weil alles in Python ein Objekt ist.

Statt eine Liste mit einem Element zu erzeugen, nur um damit eine andere Liste zu erweitern, macht man nicht, dafür gibt es append.
Statt eines Kommentars "# main" schreibt man eine main-Funktion.

`testklasse` ist eine Instanz und keine Klasse.

Code: Alles auswählen

class Wert():
    def __init__(self, test, wert):
        self.test = test
        self.wert = wert
        self.test.werte.append(wert)

class Test():
    def __init__(self):
        self.objekte = []
        self.werte = []

    def objekt_anlegen(self, wert):
        self.objekte.append(Wert(self, wert))

def main():
    test = Test()
    test.objekt_anlegen(12)
    print("Wert: ", test.werte)

if __name__ == "__main__":
    main()
Besser wäre aber, dass die Klasse Wert nichts von den Interna der Klasse Test wissen müßte.

Code: Alles auswählen

class Wert():
    def __init__(self, test, wert):
        self.test = test
        self.wert = wert

class Test():
    def __init__(self):
        self.objekte = []
        self.werte = []

    def objekt_anlegen(self, wert):
        wert_instanz = Wert(self, wert)
        self.objekte.append(wert_instanz)
        self.werte.append(wert_instanz.wert)

def main():
    test = Test()
    test.objekt_anlegen(12)
    print("Wert: ", test.werte)

if __name__ == "__main__":
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Hier ist dann noch das `werte`-Attribut komisch, denn das scheint redundant, da die Information ja auch schon in `objekte` steckt. Und ebenfalls komisch ist wenn ein Attribut genau so heisst wie die Klasse. Das kann natürlich auch an der Vereinfachung des Beispiels liegen, aber wenn das im realen Code auch so ist, dann sollte man darüber nachdenken. Ist das vielleicht so ein typischer Anfänger-Move einfach (sinnloserweise) *alles* an Attribute zu binden, auch Sachen die einfach nur lokale Namen sein sollten‽

Ich käme beim vereinfachen irgendwo bei so etwas heraus (ungetestet):

Code: Alles auswählen

class Objekt:
    def __init__(self, wert):
        self.wert = wert


class Test:
    def __init__(self):
        self.objekte = []

    @property
    def werte(self):
        return [objekt.wert for objekt in self.objekte]

    def objekt_anlegen(self, wert):
        self.objekte.append(Objekt(wert))


def main():
    test = Test()
    test.objekt_anlegen(12)
    print("Werte:", test.werte)


if __name__ == "__main__":
    main()
Edit: Wobei sich hier natürlich die Frage stellt was `Objekt` eigentlich für einen Sinn haben soll, denn Objekte mit einfach nur *einem* Wert und keinen weiteren Methoden, sind ja eigentlich nur dieser Wert selbst. Also:

Code: Alles auswählen

class Test:
    def __init__(self):
        self.werte = []

    def objekt_anlegen(self, wert):
        self.werte.append(wert)


def main():
    test = Test()
    test.objekt_anlegen(12)
    print("Werte:", test.werte)


if __name__ == "__main__":
    main()
Und da `objekt_anlegen()` hier eigentlich nur `append()` auf dem einen, einzigen Attribut ist, kann man das weiter vereinfachen zu:

Code: Alles auswählen

def main():
    werte = []
    werte.append(12)
    print("Werte:", werte)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Mubange
User
Beiträge: 3
Registriert: Mittwoch 2. August 2023, 22:10

Vielen Dank für Eure Antworten!

Ich werde mir die sehr genau und in Ruhe angucken. Da ich in der nächsten Zeit erstmal verhindert bin, kann das einen Moment dauern.
Antworten