Atrribut einer Klasse in einer anderen Klasse verwenden

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
Turing-Kepler
User
Beiträge: 3
Registriert: Montag 25. Oktober 2021, 07:57

Hallo erst einmal,
ich bin neu hier und habe wahrscheinlich eine Anfängerfrage.

Ich habe zwei Klassen.
Die zweite Klasse hat hierbei eine Methode, die ein Attribut (y) der ersten Klasse verwenden:

Code: Alles auswählen

class Klasse1:                                               
    def __init__(self)                                             
        self.x = []                                          
        self.y = []                                           
        self.z = [] 

class Klasse2:
  def __init__(self)                                             
        self.a = []                                          
        self.b = []  

 def set_test(self, y):                                  
        self.test = y
Ist das soweit korrekt oder muss ich bei "self.test = y" was anderes hinschreiben.

Danke schon mal im Voraus für eure Hilfe und viele Grüße
Turing-Kepler
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Zu wenig Kontext.
Ich vermute, du denkst, dass du die Lösung für ein Problem hast - aber möglicherweise ist dem nicht so.

Was versuchst du über dieses Konstrukt von geteilten Attributen zu lösen?
Turing-Kepler
User
Beiträge: 3
Registriert: Montag 25. Oktober 2021, 07:57

Mal angenommen ich erstelle eine Klasse mit den Attributen Produktname, Preis, Farbe (das wären die Attribute x,y,z), weil ich was verkaufen möchte.
Diese drei Attribute habe ich in der ersten Klasse.

Nun möchte ich den Preis auch in weiteren Klassen verwenden, weil z.B. für einen Onlineshop berechnet wird, wie viel ich noch zahlen muss und wie viel Rückgeld ich z.B. bekommen.
Das wären z.B. die Attribute a und b, die hierbei auch auf den Preis (y) zugreifen sollen.

Mir gehts es aber auch um das grundsätzliche Verständnis, ob ich Attribute einer Klasse auch in einer anderen Klasse verwenden kann.
Bzw. was passiert wenn ich zwei verschiedenen Klassen die Attribute gleich heißen.
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Klassen sind Baupläne, damit hast Du noch lange keine Instanz der Klasse. Und jede Instanz hat ihre eigenen Attribute.
Wenn Du im Onlineshop auf einen Artikel mit einem Preis zugreifen willst, dann braucht die Instanz Onlineshop eine oder mehrere Instanzen von Artikeln und diese haben jeweils ein Preis-Attribut.
Was hast Du denn schon an konkretem Code ausprobiert und womit hast Du Probleme?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Turing-Kepler hat geschrieben: Montag 3. Januar 2022, 13:22 Mir gehts es aber auch um das grundsätzliche Verständnis, ob ich Attribute einer Klasse auch in einer anderen Klasse verwenden kann.
Ja, das geht. Es geht sogar auf so viele verschiedene Weisen, dass es auch mit deinem Beispiel noch nicht eindeutig ist.
Bzw. was passiert wenn ich zwei verschiedenen Klassen die Attribute gleich heißen.
Nichts. eine Klasse verwaltet ihre eigenen Attribute und es gibt daher keine Konflikte.
Anders ist das bei Vererbung. Denn wenn eine Klasse von einer anderen erbt, erbt sie auch dessen Attribute

Code: Alles auswählen

class A:
    def __init__(self) -> None:
        self.a = 10


class B(A):
    def __init__(self) -> None:
        super().__init__()
        # an dieser Stelle ist self.a = 10, wird jetzt aber mit 20 überschrieben
        self.a = 20
    

b = B()
print(b.a)
Turing-Kepler
User
Beiträge: 3
Registriert: Montag 25. Oktober 2021, 07:57

Danke euch soweit für die Hilfe.
Soweit bin ich momentan.

Code: Alles auswählen

class Produkt:                                                   
    def __init__(self)                                              
        self.produkt = []                                          
        self.preis = []                                             
        self.stueckzahl = []                                   
                                                           
        self.produkt.append("Hose")                             
        self.produkt.append("Hemd")                               
        self.produkt.append("Schuhe")                                 
           
        self.stueckzahl.append(stueckzahl1)                         
        self.stueckzahl.append(stueckzahl2)                             
        self.stueckzahl.append(stueckzahl3)                         


class Zahlung:
    def __init__(self):
        self.summe = 0
        self.zu_bezahlen = 0

    def zahlung_annehmen(self, betrag):
        self.zu_bezahlen = self.zu_bezahlen - betrag

    def set_summe(self, preis):                                     
        self.summe = preis                                          
        self.zu_bezahlen = self.summe

    def get_zu_bezahlen(self):
        return self.zu_bezahlen

class Onlineshop:
    def __init__(self, stueckzahl1, stueckzahl2, stueckzahl3):  
        self.produkte = Produkt()                                                                                                    
        self.produkte.init()       
Hier werde ich dann noch Methoden erstellen, bei denen man sich ein Produkt auswählen kann und auch noch geprüft wird, ob es noch vorrätig ist.
Später wird auch die Zahlung erzeugt und zusammen mit der Stückzahl übergeben.
Vielleicht könnt ihr mir sagen, ob es soweit aber schon mal passt.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was da nicht passt ist das du mehrere Produkte in einer Instanz hast. Dann die Stückzahlen aus dem nichts. Dann ist die doppelte Daten Haltung von Summe und zu bezahlen ungewöhnlich. Stattdessen würde man eher das eingezahlte Geld aufsummieren. Getter und setter schreibt man in Python nicht.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Turing-Kepler,

ich fürchte, dass diese Modellierung auf Dauer nicht gut funktionieren wird.
Eine Klasse Produkt sollte nicht mehrere Instanzen von Produkten verwalten. Die Klasse, wie schon erwähnt, ist nur ein Bauplan für alle zu erstellenden Produkte. Sie soll nicht alle Daten aller Produkte verwalten. Das wird zu groß und unübersichtlich.

Die Klasse Zahlung ist eigentlich überflüssig. Sie enthält Methoden, die der Shop haben sollte.

Vielleicht so:

Code: Alles auswählen

class Produkt:
    def __init__(self, name, preis, stueckzahl):
        self.name = name
        self.preis = preis
        self.stueckzahl = stueckzahl


class Onlineshop:
    def __init__(self) -> None:
        # zur Vereinfachung ein Dictionary, eigentlich sollte eine Datenbank die Produkte verwalten
        self.produkte = {
            "Hose": Produkt("Hose", 0.99, 20),
            "Hemd": Produkt("Hemd", 127.12, 0),
            "Schuh": Produkt("Schuh", 12.13, 1001),
        }

    def transaction(self, produkt_name, bezahlt):
        produkt = self.produkte.get(produkt_name)
        if produkt == None or produkt.stueckzahl <= 0:
            print(f"Produkt '{produkt_name}' nicht vorhanden")
            return

        if bezahlt >= produkt.preis:
            print(f"Es wurde ein Produkt '{produkt.name}' verkauft. Rückgeld: {bezahlt-produkt.preis:0.2f} €")
            self.produkte[produkt_name].stueckzahl -= 1
        else:
            print(f"Nicht genügend bezaht um das Produkt '{produkt.name}' zu kaufen, Transaktion abgebrochen")


online_shop = Onlineshop()

online_shop.transaction("Hose", 1)
online_shop.transaction("Hemd", 200)
online_shop.transaction("Schuh", 10)
online_shop.transaction("Jacke", 10000)

"""
Ausgabe:
Es wurde ein Produkt 'Hose' verkauft. Rückgeld: 0.01 €
Produkt 'Hemd' nicht vorhanden
Nicht genügend bezaht um das Produkt 'Schuh' zu kaufen, Transaktion abgebrochen
Produkt 'Jacke' nicht vorhanden
"""
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Klasse `Produkt` läßt den Leser glauben, dass es sich um 1 Produkt handelt (was ja auch sinnvoll wäre). Du hast aber alle Produkte da drin. Das macht es dann auch schwierig, einzelne Produkte zu kaufen.
Generell sollte man nicht zusammegehörende Daten in getrennten Listen speichern, also ein Produkt besteht aus Name, Preis und Stückzahl.
`stueckzahl1`, `stueckzahl2` und `stueckzahl3` sind nirgends definiert, sollten aber als Argumente an __init__ übergeben werden. Eine Methode Produkt.init gibt es gar nicht, willst Du aber aufrufen. Diese Fehler sollten eigentlich bei Dir schon zu Fehlermeldungen beim Ausführen geführt haben, da Du davon aber nichts schreibst, befürchte ich, dass Du das Programm noch niemals hast laufen lassen.
Beim Entwickeln führt man aber ein Programm sehr oft aus (nach jeder kleinen Änderung), denn sonst kann man ja gar keine Fehler finden. Am besten schreibt man sich auch gleich sogenannte Unit-Tests, die automatisiert alle Funktionen testen und die Ergebnisse mit Erwartungswerten vergleicht.

In `Zahlung` ist die Methode `get_zu_bezahlen` überflüssig, weil man auch direkt auf zu_bezahlen zugreifen könnte. Eine Zahlung mit Summe 0 ist eigentlich unsinnig, nach dem Initialisieren sollte die Instanz einsatzbereit sein. Daher sollte das, was die Methode set_summe macht, schon in __init__ passieren.
Antworten