Klassenmethoden

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
Wololum
User
Beiträge: 6
Registriert: Montag 6. Juli 2020, 18:15

Code: Alles auswählen

class Juice:
    MING = 10

    def __init__(self, a, b):
        self.a = a
        self.b = b

    @property
    def a(self):
        return self.__a

    @a.setter
    def a(self, value):
        if value < self.MING:
            raise Exception(f"{value} is too low")
        else:
            self.__a = value

    @property
    def b(self):
        return self._b

    @b.setter
    def b(self, value):
        self._b = value

    def __add__(self, other):
        return self.a + other

    def __radd__(self, other):
        return self.a + other

    def mix(self, other):
        return (self.a + other) / 2


    def adultjuice(self, alc):
        return self.b, f"mit {alc} alc"
der Aufruf

Code: Alles auswählen

print(apple.adultjuice("5%"))
erzeugt mir die Ausgabe
('Apple', 'mit 5% alc')
ich möchte das ganze jetzt als Klassenmethode schreiben und meine Idee war

Code: Alles auswählen

@classmethod
    def adultjuice(cls, alc):
        return cls.b, f"mit {alc} alc"
das erzeugt mir allerding die Ausgabe
(<property object at 0x0000026F1FC2F548>, 'mit 5% alc')
ich hätte aber gern den wert von b, der sollte "apple" sein.
muss ich statt cls.b etwas anderes dort einsetzen oder ist mein Ansatz ganz falsch?
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Gegenfrage: Was, glaubst du, macht

Code: Alles auswählen

@classmethod
def foo(cls, bar):
    ...
?
In specifications, Murphy's Law supersedes Ohm's.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Schlage nochmal den Unterschied von einer Instanz und ihrer Klassendefinition nach. Dann sollte auch klar sein, dass eine Blaupause keine Werte haben kann.

So langsam solltest Du Dir sinnvolle Attributnamen überlegen, wenn das Beispiel immer komplexer wird. `b` sollte kein Property sein, das ist unnötig.
Bei __add__ und __radd__ erwartet man, dass man gleichartige Objekte miteinander verbindet, Du "addierst" aber ein Juice-Objekt mit einer Zahl.
__a hat plötzlich zu viele Unterstriche bekommen. Das sollte exakt einer sein.
Ein tuple ist nicht dazu gedacht, ausgegeben zu werden, Du willst wahrscheinlich bei adjultjuice einen String zurückgeben.
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das würde dann eher so aussehen (ungetestet):

Code: Alles auswählen

class Juice:
    MIN_AMOUNT = 10

    def __init__(self, amount, name, alcohol=0):
        self.amount = amount
        self.name = name
        self.alcohol = alcohol

    @property
    def amount(self):
        return self._amount

    @amount.setter
    def amount(self, value):
        if value < self.MIN_AMOUNT:
            raise ValueError(f"{value} is too low")
        self._amount = value

    def __add__(self, amount):
        return Juice(self.amount + amount, self.name, self.alcohol)

    def __radd__(self, amount):
        return self + amount

    def mixed(self, other):
        return Juice(
            self.amount + other.amount,
            f"{self.name}+{other.name}",
            self.alcohol + other.alcohol,
        )

    def add_alcohol(self, alcohol):
        return Juice(self.amount, self.name, self.alcohol + alcohol)
Wobei ich das Konzept nicht ganz schlüssig finde.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Wololum
User
Beiträge: 6
Registriert: Montag 6. Juli 2020, 18:15

Vielen Dank für die Vorschläge.
Das Programm dient jedoch nur zum lernen und meinem Verständnis, deshalb auch die mühelos gewählten Variablen. Ich werde sie dennoch umbenennen, da das wohl auch ein Fortschritt ist.
Mein eigentliches Problem war allerdings, dass ich eine normale Methode zu einer Klassenmethode umwandeln wollte die das selbe Output erzeugt, daran scheitere ich allerdings.

Gruß
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@Wololum: weil das keinen Sinn ergibt; eine Klasse ist eine Definition und hat keine konkreten Daten. Warum willst Du unbedingt eine Klassenmethode habe?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Wololum hat geschrieben: Dienstag 7. Juli 2020, 09:10 Mein eigentliches Problem war allerdings, dass ich eine normale Methode zu einer Klassenmethode umwandeln wollte die das selbe Output erzeugt, daran scheitere ich allerdings.
Wie schon mehrere Vorposter gesagt haben: das kann schon von der Idee her nicht funktionieren. self.b definierst du erst in einer Instanz der Klasse, die Klasse selber hat kein Attribut namens b.
Wololum
User
Beiträge: 6
Registriert: Montag 6. Juli 2020, 18:15

Ich studiere Mathe und hatte Programmieren 1 und 2 bestanden und musste dann mein Studium unterbrechen.
Der Fachbereich hat in dieser Zeit auf Python umgestellt und ich hatte die ersten 2 Kurse in C++ bestanden.
Jetzt werde ich im Oktober Programmieren 3 belegen und wollte mich darauf vorbereiten. Also wollte ich sämtliche Themen die dort vorrausgesetzt werden abarbeiten. Dazu gehören auch Klassenmethoden deshalb wollte ich mich damit beschäftigen und zu allem mal ein kleines Beispiel programmieren.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Klassenmethoden werden meist dafür benutzt, um Instanzen einer Klasse zu erzeugen, um flexibler zu sein als mit __init__. Ich kenne Deine Unterlagen nicht, und auch nicht, wie da Klassenmethoden erklärt werden, aber für Dein Beispiel machen die halt keinen Sinn.
Wololum
User
Beiträge: 6
Registriert: Montag 6. Juli 2020, 18:15

Ok, vielen Dank für die Hilfe. Ich schaue mich mal nach einem geeigneteren Beispiel um.

Gruß
Antworten