Seite 1 von 3
Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Donnerstag 26. Dezember 2013, 18:06
von BSA
Moin Leute,
ich weiß, das ist wahrscheinlich nicht die erste Frage hier. Drei Threads dazu hab ich mir hier dafür durchgelesen, und etliche Erklärungen und Tutorials sowie Uni-Referate im WWW - komme aber trotzdem auf keinen grünen Zweig...
Es geht um OOP und Variablen.
Ich habe schon an etlichen Stellen gelesen, dass wo möglich, globale Variablen vermieden werden sollen. Den Grund habe ich, denke ich, auch verstanden. Zu fehleranfällig und man weiß nie, welche Instanz sie nun verändert etc pp...jedenfalls ist das nicht die eleganteste Lösung.
Ich stehe nun vor folgendem "Problem":
- Ich habe zwei Klassen, mit jeweils mehreren Methoden.
- Jede Klasse (1 & 2) benötigt dieselben (also sämtliche) Variablen für ihre Methoden.
- Nicht jede Methode einer Klasse benötigt jedoch alle Variablen
- global
variable soll umgangen werden
- die meisten Funktionen benötigen die Variablen lesend
- manche Methoden müssen Schreibrecht besitzen
( es macht auch nix, wenn jede Methode ein Schreibrecht für jede Variable besitzt, da die
Funktionsweise zum Schreiben, wenn nicht benötigt, auch nicht im Code enthalten ist sondern nur auf den Wert der Variable zugegriffen werden muss)
Mit __init__ habe ich es versucht, später aber dann erfahren, dass die Variablen nur lesend von anderen Methoden/Instanzen und/oder Klassen benutzt werden können - und selbst da sitzt bei mir irgendwo der Wurm.
Mit globalen Variablen hab ich es probiert, und das funktioniert sogar beinah so weit, aber man will sich ja auch keinen absichtlich allzu schlechten Stil angewöhnen...
Wahrscheinlich ist die Lösung recht einfach, ich suche jedoch schon seit gestern nach ihr. Und irgendwie steh ich grad am Bahnhofsgleis und sehe weit und breit keinen Zug mehr vorbeifahren...
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Donnerstag 26. Dezember 2013, 18:26
von Hyperion
BSA hat geschrieben:
Es geht um OOP und Variablen.
Du meinst hier wohl eher "Attribute"!
BSA hat geschrieben:
Ich stehe nun vor folgendem "Problem":
- Ich habe zwei Klassen, mit jeweils mehreren Methoden.
- Jede Klasse (1 & 2) benötigt dieselben (also sämtliche) Variablen für ihre Methoden.
- Nicht jede Methode einer Klasse benötigt jedoch alle Variablen
Genau da liegt doch schon das Problem! Deine Modellierung des Problems deckt offenbar nicht wirklich das Problem ab, denn dann wären die Klassen in sich stark (stärker)
kohäsiv. Vielleicht brauchen die Methoden ``a()`` und ``b`` aus Klasse ``A`` die selben Attribute wie die Methoden ``c`` und ``d`` aus ``B``. Dann müsste man die Klassen anders "aufteilen", so dass eine neue Klasse genau die Methoden hat, die wirklich (fast) alle Attribute benötigt.
Und wenn zwei Klassen durchgängig dieselben Attribute benötigen, dann kann es sein, dass man in Wahrheit gar keine zwei Klassen braucht, sondern *eine* diese Aufgabe übernehmen kann; oder man benötigt ein drittes Objekt, welches durch die beiden anderen lediglich manipuliert wird; oder man kann Dinge durch Vererbung zusammenfassen, oder...
Du solltest hier einfach konkreter werden und mal die Code zeigen und das Problem zusätzlich textuell erläutern; ich denke nur dann kann man Dir wirklich einen Tipp geben, wo Du ansetzen solltest!
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Donnerstag 26. Dezember 2013, 19:42
von BSA
Ja, sehr gerne. Das werd ich machen.
Ich bin jetzt noch grad auf Arbeit und per Netbook & UMTS im Web, aber sobald ich zu Hause bin, werd ich mich dransetzen und die beiden Klassen zusammensetzen. Die zweite scheint (ist) wirklich unnötig...
Ich habe ursprünglich drei gehabt, aber ich denke wenn ich das ganze wirklich so einfach wie nur möglich versuche zu gestalten, könnte es vielleicht (zumindest oberflächlich) auch so funktionieren...mal sehen.
Ich schicke dann den überarbeiteten Code hoch, der aktuelle ist unnötig...
Den Link zur Kohäsion werd ich mir auch nachher gleich noch reinziehen!
Danke schonmal soweit !
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Donnerstag 26. Dezember 2013, 23:57
von BlackJack
@BSA: Wobei die Beschreibung mit dem `__init__()` auch sehr eigenartig ist. *Dort* sollten nach Möglichkeit alle Attribute eingeführt und an sinnvolle Werte gebunden werden, denn die Methode soll ein Objekt ja initialisieren und in einem benutzbaren Zustand hinterlassen. Und die Attribute kann man dann natürlich aus jeder anderen Methode auch neu binden, also „beschreiben”.
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Sonntag 29. Dezember 2013, 23:04
von BSA
Moin Leute,
ich habe das Programm nun soweit geändert, dass es lauffähig ist. Ob der Code strukturiert, schön und "richtig" ist, hoffe, aber glaube ich nicht...aber zumindest: es läuft erst einmal. Von hier aus kann ich dann ja weitergehen.
Zu Beginn: Wenn man das Programm etwas "ärgert" (Sound im Konfig.menü nach je einem Durchlauf der play_game() ständig ein- und ausschalten), kommt hin und wieder mal ein Fehler, dass die globale Variable der jeweiligen Sound-Datei nicht gefunden wurde. Ich könnte das Problem natürlich bei jedem 'pygame.mixer.music.load()' mit einem try/except abfangen, was ja aber am grundlegenden Problem nichts ändern würde, von daher hab ich es so gelassen.
Beschreibung des Codes:
- python3 - pygame selbst kompiliert, daher nicht für jeden sinnvoll nutzbar
- eine einzige Klasse: 'Game()'
- __init__ vermutlich falsch angegangen - nicht richtig genutzt?
- 8 Methoden in Klasse 'Game()' - jede Methode kümmert sich - mMn - um genau eine Sache, oder anders: um eine Frage- bzw. Einstellung
- der Code ist wahrscheinlich nicht besonders stark strukturiert, sieht evtl. auch nicht sehr gut aus und ist nicht immer und in jeder Situation 100% funktional...
- die Methode zur Textausgabe 'reading()' ist falsch betitelt, wird aber noch umbenannt - die Text-Datei kann ich gerne nachschieben
- die vier Sound-Dateien sind von einer Seite für Java-Programmierer entnommen und lt. der Seite frei zur Verwendung gestellt, wer mag, dem kann ich die links geben oder auch die Namen der Dateien plus die Webseite, HIER hochladen scheint mir unnötig (sollte alles mal auf github kommen, lege ich sie dort natürlich im Ordner mit ab)
- die Instanz-Variablen innerhalb der Methoden für die jeweilige Anwender-Eingabe sollten mittlerweile alle mit "inp_xyz" anfangen, es kann aber sein, dass ich etwas übersehen habe - auch die Namen für div. Attribute/Instanz-Variablen sind evtl. noch unklar/unnötig gewählt/erstellt/umbenannt
Ich habe versucht, die __init__ so zu nutzen, um die Attribute erst dort zu initialiseren, Bsp.
Leider sagt mir das Programm dann immer wieder, dass das Objekt Game() keine Attribut sel_menu besitzt, weswegen ich auf die ursprüngliche Art geswitched habe, die ich im Code auch benutzt habe - also noch vor der __init__ ein Attribut zu erstellen, und in der __init__ auf eben diese zu verweisen.
Ist wahrscheinlich nicht richtig, komme da aber irgendwie nicht weiter...
So, ich freue mich wie immer über eure Meinung, Kritik und natürlich Verbesserungsvorschläge
Grüße
BSA
Für den Code, klick mich
Danke auch nochmal für den Link zur Kohäsions-Erklärung, das zeigt einem schonmal die richtige Logik, an der Umsetzung hapert's leider natürlich noch!
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Sonntag 29. Dezember 2013, 23:11
von /me
BSA hat geschrieben:So, ich freue mich wie immer über eure Meinung, Kritik und natürlich Verbesserungsvorschläge

Du erstellst überhaupt keine Instanz deiner Klasse. Die __init__-Methode wird folglich nie durchlaufen.
So wie du die Klasse momentan einsetzt ist sie, mit Verlaub gesagt, völliger Humbug. Dir fehlen ganz offensichtlich noch die Konzepte von OOP. Anhand welches Tutorials/Buches lernst du denn? Wie können wir dir da weiterhelfen?
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Sonntag 29. Dezember 2013, 23:36
von BlackJack
@BSA: So einige von den ”Methoden” sind auch gar keine weil sie das Objekt auf dem sie existieren überhaupt gar nicht brauchen. In solchen Fällen sollte man einen guten Grund haben die überhaupt in einer Klasse zu definieren und nicht einfach als das was sie sind: Funktionen. Klassen an sich sind ja kein Selbstzweck. Wenn eine Klasse keinen Sinn macht, verkompliziert sie den Code nur unnötig.
``for i in range(1):``? Ernsthaft‽ Was in dem ``try``-Block in der Schleife überhaupt schief gehen soll ist mir auch nicht so ganz klar.
Bevor Du Dich an Klassen wagst gewöhn Dir bitte ``except:`` ab! Zwischen ``except`` und dem Doppelpunkt sollte immer konkret stehen *welche* Ausnahme(n) behandelt werden soll(en).
Und `sys.exit()` ist auch noch/wieder in Funktionen/Methoden wo man das nicht verwenden sollte.
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 10:34
von Sirius3
Zusätzlich zu Meinen Vor-Schreibern:
In »reading« steht zweimal exakt der selbe Code. Dateien sollten mit »with« geöffnet werden und am besten iterierst Du gleich über das Fileobjekt, dann mußt Du nicht erst die Zeilen mühsam splitten.
Viele »if«-Abfragen enthalten in beiden Zweigen den selben Code, dieser kann dann hinter die Abfrage gezogen werden.
Du hältst Dich strikt an eine Zeilenlängenbegrenzung, was manchmal zu sehr unleserlichem Code führt. Das ist ein Zeichen dafür, dass Du zu komplexe Funktionen schreibst und diese besser in mehrere aufspalten solltest. Soweit ich sehen kann ist das »\« fast überall überflüssig.
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 10:47
von HarteWare
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 11:05
von BlackJack
Beim Tip von HarteWare läufts mir bei der Erklärung von `__del__()` und ``del`` kalt den Rücken runter. Warum können Autoren von Material für Anfänger `__del__()` nicht einfach schweigend übergehen statt so einen falschen Unsinn zu schreiben…
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 11:07
von Sirius3
HarteWares Tip hat geschrieben:Die __del__-Methode wird automatisch aufgerufen, wenn das Objekt nicht mehr gebraucht wird, und es gibt keine Garantie dafür, wann dies der Fall ist. Wenn Sie dies explizit tun wollen, müssen Sie einfach die del-Anweisung benutzen, die wir bereits aus früheren Beispielen kennen.
Hier wird wieder »__del__« als etwas gezeigt, was man im normalen Programmieralltag sinnvoll einsetzen kann, das ist aber nicht der Fall. Der zweite Satz ist schlicht falsch!
Im Absatz darunter wird gleich das Märchen von „privaten Variablen“ erzählt. Schaurig.
Allgemein scheint der Author von PEP8 nicht viel zu halten.
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 12:45
von HarteWare
mmm, dann war das wohl ein Fehler davon auszugehen, dass das wirklich einfach nur eine Übersetzung von
dem hier ist, ohne es mal zu lesen. In dem Fall, sorry...
LG
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 13:18
von BlackJack
@HarteWare: Es ist eine Übersetzung einer älteren Version davon. Der Autor geht auf Rückmeldungen ein und verbessert sein Buch entsprechend.

Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 13:30
von NoPy
Wie müsste man denn dieses einfache Beispiel mit dem "Bevölkerungszähler" in Python umsetzen?
Wenn __del()__ und del nicht so funktionieren, wie in der Übersetzung dieses Buches beschrieben, wie ginge es dann?
Also angenommen, "Personen" werden erschaffen und verschiedenen Gremien zugeordnet (Parteien, Vereinen, Familien ...) und aufgrund des Eigenlebens dieser Objekte werden diese Personen dann aus den Gremien herausgeworfen und wenn das letzte Gremium eine Person herausgeworfen hat, dann wird irgendwann der Garbage- Collektor aktiv.
Wie bekomme ich denn heraus, wieviele Personen noch da sind? (mir ist klar, wenn eine Person aus dem letzten Gremium verschwand, dann ist sie zwar noch im Speicher, aber kein Mensch weiß mehr, wo, sie ist also quasi scheintot. Wenn ich mit del das Löschen explizit anstoßen könnte, wäre das Problem natürlich weg. Mir ist auch klar, dass - wenn ich explizit das Löschen anstoßen kann, ich auch meinen Zähler herunterzählen könnte. ABER: Dazu muss ich wissen, was alles vom Entwickler der "Personen"- Klasse als notwendig erachtet wurde.)
Daher die Frage an diesem Einfachen Beispiel: WIE (und bitte nicht mit WARUM gegenfragen, das weiß ich auch noch nicht, ich lerne ja noch)
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 14:09
von Sirius3
@NoPy: Ich stelle dennoch eine Warum-Frage: Warum interessiert es Dich wie viele »Person«en insgesamt existieren? Diese Anzahl ist ja einigen Unsicherheiten unterworfen: Objekte können noch nicht von der Garbage-Collection erfasst worden sein. Es gibt temporäre Kopien für irgendwelche Operationen, es gibt Objekte, die sich wie ein »Person«-Objekt verhalten, aber Instanzen einer anderen Klasse sind.
Aus all diesen Gründen gibt es selten Bedarf an Objekt-Zählern oder ähnlichem. Die Anzahl der Objekte in einem bestimmten Kontext ist dagegen einfach und jederzeit ermittelbar, zum Beispiel die Länge einer Liste.
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 14:11
von BlackJack
@NoPy: Das sauberste und „unmagischste” Variante wäre es sich von allen Gremien die Mitglieder geben zu lassen, die in ein Mengenobjekt zu stecken (`set`) und dann zu schauen wie gross das ist. Und bevor ich da mehr „Magie” ins Spiel bringe, würde ich tatsächlich erst einmal nach dem Warum fragen.
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 14:37
von NoPy
Ist eine Antwort, danke. (ist natürlich aufwändiger, als einfach einen Instanzzähler auszuwerten, aber geht eben nicht anders)
Nichts gegen WARUM- Fragen, aber meine grundsätzliche Herangehensweise an Aufgaben ist es, einen Weg zu suchen und nicht die Sinnhaftigkeit der Aufgabenstellung in Frage zu stellen (und das, obwohl ich nicht in grün/braun- gemustertem Outdoor- Outfit sinnlos durch die Gegend gerobbt bin).
Daher lerne ich in der Regel mehr, wenn ich aus vorhandenen Möglichkeiten eine möglichst geeignete Lösung suchen kann und möchte die Möglichkeiten kennenlernen.
Eine Antwort, die darauf abzielt, die Frage in Frage zu stellen, ist da meist nicht zielführend.
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 14:49
von Hyperion
NoPy hat geschrieben:Ist eine Antwort, danke. (ist natürlich aufwändiger, als einfach einen Instanzzähler auszuwerten, aber geht eben nicht anders)
Code: Alles auswählen
class SomeObject: pass
some_special_objects = {SomeObject(), SomeObject(), SomeObject()}
len(some_special_objects)
> 3
Hm... das ist aufwendiger, als einen Instanzzähler in die Klasse einzubauen... sehe ich irgend wie anders, wenn ich mir den Code angucke

Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 14:59
von Sirius3
@NoPy: Aus den von mir angeführten Gründen ist ein Zähler keine Lösung für reale Probleme. Wenn die Aufgabe ist, die Anzahl der Personen in Vereinen, Parteien und Familien zu ermitteln, dann sieht eine Lösung so aus:
Die Objekte »Partei«, »Verein« und »Familie« haben jeweils ein Attribut »members«, das ein iterierbares Objekt über alle Mitglieder liefert.
Code: Alles auswählen
def collect_all_persons(groups):
result = set()
for group in groups:
result.update(group.members)
return result
def number_of_all_persons():
all_persons = set()
for groups in (parteien, vereine, familien):
all_persons.update(collect_all_persons(groups))
return len(all_persons)
Re: Variablen innerhalb von Klassen & Methoden übergeben
Verfasst: Montag 30. Dezember 2013, 15:02
von BlackJack
@NoPy: Einfach einen Instanzzähler geht ja nicht, also selbst wenn es den gäbe oder der einfach möglich wäre, die Gründe hat Sirius3 ja schon genannt.
Du verwendest Zeit darauf Aufgaben zu lösen die letztendlich keinen Sinn haben, beziehungsweise wo man den Sinn gar nicht weiss? Wenn mir der Sinn einer Aufgabe nicht klar ist, dann kläre ich das *erst*. Wahrscheinlich hat sie sogar einen Sinn, nur wenn ich den Sinn nicht (er)kenne, kann ich doch auch nicht sicher sein das meine Lösung überhaupt die Anforderungen erfüllt. Bei der Frage nach der Anzahl der existierenden Mitglieder-Objekten muss ich doch zum Beispiel die Frage klären ob die Antwort von der Grösse der Gesamtmenge der Mitglieder in den Gremien abweichen darf. Falls das nicht der Fall sein darf, und diese Anforderung erscheint mir sinnvoll, dann scheidet ein Instanzzähler ja sowieso schon aus und ich brauche gar nicht erst versuchen den irgendwie umzusetzen.