Ich bin so frei, mich hier als TO noch einmal einzumischen. Keiner von euren Beiträgen hat mich verwirrt oder in eine Richtung gedrängt. Ja, ich habe das Programmieren mit BASIC erlernt und war die letzten Jahre ausschließlich in Dialekten unterwegs (BlitzBasic, PureBasic u. a.), aber ich habe den Weg zu Python gefunden und natürlich möchte ich OOP nutzen, das versteht sich von selbst. Ich denke, dass man viele Probleme durch funktionale Programmierung lösen kann (auch wenn es manchmal umständlich sein mag), aber die OOP hat durch die Möglichkeit der sauberen Strukturierung und vor allem Vererbung unglaublich charmante Möglichkeiten, das ist für mich schnell deutlich geworden.
Ja - es waren "quatschige", kurze Beispielcodes - das Projekt, an dem ich bastele, ist etwa 700 Zeilen lang und natürlich habe ich versucht, das "Kernproblem" herauszunehmen (was einem Anfänger vielleicht nicht einmal gelingt). Ich möchte OOP "atmen", ich möchte es verstehen. Bisher habe ich funktional entwickelt, so denke ich (noch). Also bin ich auf der Suche nach einer Stilistik gewesen, die meinem eigenen, persönlichen Stil entspricht. Ich habe mein Programm funktional entwickelt und zusätzlich OOP verwendet, weil ich Objekte (Plural!) brauchte, die voneinander erben sollten, weil sie bestimmte Funktionalität teilten, an anderen Stellen differieren. Ich habe mit tkinter programmiert - und absolut richtig, wie ihr schon antizipiert habt: Ich hatte zwei Funktionen, wo ich auf globale Variablen zurückgegriffen habe. Das war bei meinen Basic-Programmen Standard (und ehrlich gesagt, hatte ich noch nie ein Problem mit einer "fälschlichen" Überschreibung oder Problemen bei der Wartung - allerdings habe ich nicht im Team gearbeitet und kein Programm war länger als etwa 10000 Zeilen). Aber das ist nicht der pythonic way of life - das ist mir klar.
Also habe ich angefangen, mein funktional konzipiertes Programm in eine Klasse umzudekorieren (und ich meine keinen decorator, sondern verwende das Wort, weil mir klar ist, dass es so nicht Fisch und Fleisch ist). Ich habe fleißig mit Klassenvariablen gearbeitet und sehe hier durchaus schon einen Unterschied zu der rein funktionalen Lösung, obwohl es letztlich eine Spiegelung des Programms ist. Das Programm ist in sich gekapselt, dass "von außen" zugegriffen werden kann, ist gewollt. Das Programm lief, wie erwartet. Und ich empfand es auch nicht als "Schande", denn ein einziges Objekt zu erzeugen, nur damit es "objektorientiert" ist, fand ich nicht naheliegend oder nötig. Wozu app=App(), wenn doch sowieso nur der Hauptcode ausgeführt wird und ich gar keine Instanz benötige? Wiederverwertbar soll dieser Hauptcode auch nicht sein.
Nun bin ich aber keineswegs "beratungsresistent", wie es jetzt scheinen mag - im Gegenteil: Ich will lernen. Ich schätze eure Kompetenz und finde es beachtlich, dass ihr eure Zeit und euer persönliches Engagement in solch ein Forum steckt, ohne monetär entlohnt zu werden. Wenn ich mir ansehe, wie viele Beiträge ihr geschrieben habt - Hut ab!
Also: Ich habe den Code nun instanziert, bin aber auf das Problem gestoßen, dass ich die Klassenvariablen schmerzlich vermisse, weil ich es nicht hinbekomme, die einzelnen Objekte miteinander vernünftig kommunizieren zu lassen. Wenn ich command=funktion von der Button-Klasse von tkinter nutze, habe ich ja keine Rückgabewerte. Ich muss auf Attribute innerhalb der Klasse zugreifen. Kein Problem. Was aber, wenn ich auf Attribute einer anderen Klasse zurückgreifen möchte? Mit der Klassenvariablen-Methode war das ein Kinderspiel, aber bei einer strengen Objektbehandlung stehe ich (noch?) auf dem Schlauch.
Die Herausforderung in meinem Programm ist, dass die eine Klasse (nennen wir sie einfach App), die das eigentliche Programm darstellt, auf andere Klassen zurückgreift, die ihrereseits Widgets erstellen und ihre eigenen Methoden mitbringen. Sie müssen aber auf Attribute der Klasse App (nein - korrigiere - nun auf das Objekt der Klasse App

) Zugriff nehmen.
Wieder zwei quatschige Beispiele, um mein Problem zu schildern bzw. ein Ansatz, wie es vielleicht zu lösen wäre:
Klassen-Variablen (der schlechte Weg, das habe ich verstanden und will ich ja besser machen, aber hier noch einmal zur Verdeutlichung):
Code: Alles auswählen
import tkinter as tk
class App:
summe = 0
root = tk.Tk()
objekte = []
def lets_go():
tk.Button(master=App.root, text="Objekt erzeugen", command=App.make_object).pack()
def make_object():
App.objekte.append(AnotherClass())
print("Objekte in der Liste:", len(App.objekte))
class AnotherClass:
def __init__(self):
tk.Button(master=App.root, text="summe +1", command=self.addiere).pack()
def addiere(self):
App.summe += 1
print("Summe:", App.summe)
def main():
App.lets_go()
App.root.mainloop()
if __name__ == "__main__":
main()
Ich habe verstanden, dass euch bei so einer Version die Haare zu Berge stehen, obwohl ich den Mehrwehrt gegenüber der rein funktionalen Lösung mit dem Befehl "global" durchaus schon sehe - und das Programm arbeitet und macht Spaß. Aber ich will es ja besser machen.
Mein neuer Ansatz (der aber vielleicht auch schon der falsche ist?):
Code: Alles auswählen
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.summe = 0
self.objekte = []
tk.Button(master=self, text="Objekt erzeugen", command=self.make_object).pack()
def make_object(self):
self.objekte.append(AnotherClass(self))
print("Objekte in der Liste:", len(self.objekte))
class AnotherClass:
def __init__(self, main_class):
self.main_class = main_class
tk.Button(master=self.main_class, text="summe +1", command=self.addiere).pack()
def addiere(self):
self.main_class.summe += 1 # So macht man das dann?
print("Summe:", self.main_class.summe)
def main():
app = App()
app.mainloop()
if __name__ == "__main__":
main()
Ist es so "richtig" gelöst? Muss ich also bei der Erzeugung der Objekte aus meinem App-Objekt das App-Objekt selbst (self) an die AnotherClass() übergeben? Für mich ist das noch recht beschwerlich und wirkt tatsächlich "kompliziert" im Gegensatz des funktionalen Ansatzes, aber ja - ich gebe mein Bestes.
Und ich muss doch darauf hinweisen, dass die meisten Tutorials über tkinter da draußen NICHT objektorientiert aufgebaut sind. Die besten Ansätze habe ich hier gefunden:
https://www.pythontutorial.net/tkinter/ ... ed-window/
Aber was sonst so unterwegs ist, ist veraltet oder für einen NOOB kaum lesbar ...
Ich hoffe, wir können den Fachdiskurs unter euch (nenne ich es einmal so) aufgeben und zurück auf meine "ganz kleinen" Probleme kommen. Die Grundsatzdiskussion ist IMHO nicht notwendig. Ich will ja folgen und brav sein! Und ich freue mich über alle Beiträge gleichermaßen - in welche Richtung sie auch gehen. Jeder Mensch ist anders, jeder denkt anders, jeder hat andere Wege, die Probleme anzugehen. Und Python ist so flexibel, dass es die unterschiedlichsten Werkzeuge anbietet, um den Weg zu gehen, wie auch immer man ihn gestalten möchte. Python wird damit vielen Denkweisen gerecht. Das ist doch klasse! Das ist kein Bug.
Herzliche Grüße
Onomatopoesie