Seite 1 von 1
Klassen-Variable initiieren?
Verfasst: Dienstag 29. März 2022, 11:43
von efix
Moin,
ich mache gerade zum erstmal was mit Klassen in Python und ich wollte mal fragen ob das so richtig ist wie ich die Variabeln initiiere? Oder wie ihr das machen würdet...
Code: Alles auswählen
class Calculate:
zahl1 = 0
zahl2 = 0
def __init__(self):
self.zahl1 = self.getzahl()
self.zahl2 = self.getzahl()
def getzahl(self):
return float(input("Geben Sie eine Zahl ein: "))
cal = Calculate()
print(cal.zahl1)
Also funktionieren tut es!
Viele Grüße
Re: Klassen-Variable initiieren?
Verfasst: Dienstag 29. März 2022, 11:51
von __deets__
Das ist falsch so, weil deine Deklarationen auf Klassen-Ebene (also direkt unter der class-Instruktion) nicht das sind, was du glaubst das sie sind. Dabei handelt es sich naemlich *nicht* um Instanzvariablen, was du eigentlich willst. Sondern um Klassenvariablen, die sich *alle* Instanzen deiner Klasse teilen. Man sieht leider draussen gelegentlich Code, der das so macht, aber der ist ueblicherweise falsch.
Die Details hier sind subtil und vielfaeltig, aber die Faustregel ist ganz einfach: ALLER Zustand, den das Objekt haben soll, MUSS in __init__ angelegt werden. Keinerlei Instruktionen auf Klassenebene, ausser Methoden.
Re: Klassen-Variable initiieren?
Verfasst: Dienstag 29. März 2022, 12:03
von efix
Danke für die Antwort! Ich kann mir das so noch nicht vorstellen. Kannst du mir ein Beispiel zeigen wie es richtig ist dann verstehe ich das besser...
Re: Klassen-Variable initiieren?
Verfasst: Dienstag 29. März 2022, 12:39
von Sirius3
Funktionen werden nach Tätigkeiten benannt, Klassen nach Dingen. Also statt `Calulate` `Calculation`. Abkürzungen benutzt man nicht.
`getzahl` benutzt `self` gar nicht, warum ist das dann eine Klassenmethode? `zahl` ist auch das einzig deutsche Wort. Bleib bei einer Sprache bei der Benennung. Die Klasse ist sehr kurz, da kommt sicher noch was dazu, so dass man noch nicht sagen, ob bei Deiner Aufgabe überhaupt eine Klasse nötig ist.
Code: Alles auswählen
def get_number():
return float(input("Geben Sie eine Zahl ein: "))
class Calculation:
def __init__(self):
self.number1 = get_number()
self.number2 = get_number()
calculation = Calculation()
print(calculation.number1)
Re: Klassen-Variable initiieren?
Verfasst: Dienstag 29. März 2022, 12:40
von efix
Ok. Ich denk drüber nach. Aber warum definierst du Funktion außerhalb der Klasse?
Re: Klassen-Variable initiieren?
Verfasst: Dienstag 29. März 2022, 12:42
von Sirius3
Die Frage sollte anders herum gestellt werden, warum hast Du eine Funktion in eine Klasse gesteckt, obwohl sie nichts von der Klasse braucht.
Re: Klassen-Variable initiieren?
Verfasst: Dienstag 29. März 2022, 12:48
von efix
Aber die Funktion wird doch von dem Objekt beim initiieren benutzt damit ist sie doch ein wesentlicher Teil der Klasse, oder nicht? Kann ich so noch gar nicht sagen...
Ich denk drüber nach warum...
Re: Klassen-Variable initiieren?
Verfasst: Dienstag 29. März 2022, 13:10
von __deets__
Auch hier wieder: wenn die Funktion keinen Zugriff auf self benoetigt, muss oder sogar sollte sie *nicht* Teil der Klasse sein.
Re: Klassen-Variable initiieren?
Verfasst: Dienstag 29. März 2022, 13:14
von __blackjack__
@efix: Es werden auch die Funktionen `input()` und `float()` beim Initialisieren benutzt, die sind ja auch nicht in der Klasse definiert. Und falls Du eine weitere Klasse schreibst, wo der Benutzer Zahlen eingeben muss, dann müsstest Du dort nach der Logik die gleiche ”Methode” noch mal schreiben, statt dass Du bereits eine Funktion hast, die in beiden Klassen benutzt werden kann.
Es gibt seltene Fälle in denen eine Funktion so stark an eine Klasse gebunden ist, dass man sie als „statische Methode“ in die Klasse schreibt. Dann aber auch ohne das unbenutzte `self` und mit `staticmethod()` dekoriert.
Es ist übrigens auch ungewöhnlich Benutzerinteraktion in eine `__init__()` zu stecken. Überhaupt hält man die `__init__()` oft eher schlank/dumm, weil es das Testen und in anderen Kontexten verwenden einfacher macht, wenn sich leicht Exemplare erstellen lassen ohne zu viele Abhängigkeiten ”nach draussen” zu haben, also insbesondere Eingaben, aber auch Ausgaben.
Aufbauend auf dem Beispiel von Sirius3 beispielsweise:
Code: Alles auswählen
#!/usr/bin/env python3
def get_number():
return float(input("Geben Sie eine Zahl ein: "))
class Calculation:
def __init__(self, number_a, number_b):
self.number_a = number_a
self.number_b = number_b
def main():
calculation = Calculation(get_number(), get_number())
print(calculation.number_a)
if __name__ == "__main__":
main()