Ich les' mich im Moment wieder ein wenig in wxPython ein und bin gerade beim Event-driven und der Übersichtlichkeit halber habe ich die einzelnen Bestandteile in eigene Funktionen ausgelagert. Das ganze sieht nun so aus:
Code ausgelagert
Meine Frage ist: Ist das eine gute Idee oder macht es zuviele Probleme? Ich würde anschließend auch meine Sizers mit den Widgets in eine eigene Funktion packen. Bei sehr vielen Sizern und vielen Widgets erhöht das die Übersichtlichkeit enorm. Jedoch braucht man bei vielen Sachen, wie eben dem self.menuQuit das self noch davor, vielleicht stört das... wenn es im Init wäre, bräuchte man das ja nicht. Ist das guter Stil oder soll ich es lassen?
Bindings, Menü, ... in Funktionen auslagern... Gute Idee?
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo BlackVivi!BlackVivi hat geschrieben:die einzelnen Bestandteile in eigene Funktionen ausgelagert.
Ich kann dir nur sagen was ich davon halte und wie ich es mache. Das soll nur eine Empfehlung sein.
Ich brauche länger um Dinge wieder zu finden wenn ich die Erstellung der GUI auf mehrere Funktionen verteile. Für mich ist es also viel schwerer, das Programm zu durchschauen und Fehler zu finden, wenn ich den GUI-Aufbau auf mehrere Funktionen verteile. Außerdem ist es auch mehr Schreibarbeit. Du musst Vieles in Instanzvariablen halten und musst dich immer darum kümmern, dass die benötigten Objekte auch wirklich an die Funktionen übergeben werden. -- Es macht die GUI-Erstellung, in meinen Augen, komplizierter, wenn diese auf mehrere Funktionen aufgezeilt wird.
Ein Frame bekommt bei mir immer eine eigene Klasse. Oft verwende ich für Panels, mit vielen Widgets oder einer eigenständigen Funktion, ebenfalls eigene Klassen. Also immer dann, wenn etwas gut abgetrennt werden kann (z.B. die Panels, die in ein Notebook gelegt werden), dann bekommt es eine eigene Klasse spendiert. Ich schreibe dir dafür noch ein kleines Beispiel. Später.
Zu diesem Codeschnipsel habe ich auch noch etwas zu sagen:
Code: Alles auswählen
class Frame(wx.Frame):
def __init__(self, parent=None, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE,
title="", name="frame" ):
wx.Frame.__init__(self, parent, id, title, pos, size, style)

Code: Alles auswählen
def __init__(self, parent = None, name = "Beispiel")
- id: Wird nie gebraucht
- pos: selten. Und wenn doch, dann kann man es immer noch in die __init__ integrieren
- size: Wenn man alles richtig macht, dann braucht man size so gut wie nie. Die Größe des Frames wird meistens dynamisch von den darin enthaltenen Widgets bestimmt. Man braucht size nur in Ausnahmefällen. Und in diesen Fällen kann man es immer noch in die __init__ integrieren.
- style: (wie pos)
- name: Wird so gut wie nie gebraucht
Code: Alles auswählen
def Menu(self):
...
def Bindings(self):
...
def OnMenuQuit(self, event):
...
"Menu" ist ein Ding, ein Objekt. Aber kein Name für eine Funktion, die etwas macht. Was macht sie denn?
"Bindings" ist irgendetwas, aber keine Funktion, die Bindings erstellt. Das ist aus diesem Namen nicht ersichtlich. Gute Namen erhöhen die Lesbarkeit deines Codes.
Du willst sicher von einem Menüpunkt aus das Frame schließen. Du willst evt. auch von einem Button einer Toolbar aus dein Frame schließen. Vielleicht möchtest du nach getaner Arbeit dein Frame auch automatisch schließen. Schade, dass du "OnMenuQuit(self, event)" nur als Eventhandler für das Menü verwenden kannst.

Code: Alles auswählen
def close_frame(self, event = None)
Meine Vorschläge: Wobei ich aber zu bedenken gebe, dass ich persönlich das Menü und die Bindings in __init__ erstelle um beim Durchlesen des Codes ein flüssigeres Bild vor Augen zu haben (ohne ständig hin und her springen zu müssen).
Code: Alles auswählen
def create_menu(self):
...
def create_bindings(self):
...
def close_frame(self, event = None):
self.Close(True)
mfg
Gerold

http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Hallöschen Gerold,
das Frame war nur'n Beispiel, ich hab den richtigen Namen rausgelöscht, weil ich das für'n Projekt für mein Praktikum machen, Datenschutz etc... Also, in einem wirklichen Frame würde ich den Namen eher weniger benutzen. Ich arbeite momentan das Buch "wxPython in Action" durch und da stehen halt diese Empfehlungen, dass man diese Argumente benutzen soll und sowas. Also, dass man pos, size und so weiter überhaupt nicht braucht, wusste ich gar nicht. Deswegen bin ich dir für diesen Ratschlag überaus dankbar!
Die Sache mit dem Menu und Binding hatte ich bereits vorhin geändert, nachdem ich einen Gedanken daran verschwendet habe, hab ich mir gedacht: "Hmpf oO' einfach nur Menu ist unklug." Aber trotzdem danke. Ich benutze keine Unterstriche, weil ich gern in wxPython Programmen deren Konvention behalten möchte. Aber darüber denke ich nochmal nach
Die Sache mit dem close_frame hatte ich auch schon vorhin gemacht, aber so sinnvoll ist es in meinem Fall nicht, da ich es sonst nicht aufrufen möchte.
Zu deiner persönliche Vorliebe: Ich hab einen tollen Codesnippet im Buch gefunden, der die Teiel sozusagen "dynamisch" erstellt und das ganze ohne redundanzen wesentlich flüssiger und schöner für mich darstellt. Der Codesnippet ist fast komplett aus dem Buch übernommen!
Code ausgelagert...
(In dem Code hab ich jetzt die Namenskonventionen gemischt, dass ist mir klar. Ich bin mir noch nicht sicher, wie ich es genau mache :/ Ich tendiere aber natürlich zu PEP8, obwohl wxPython sagt, dass man sich an der Namenskonvention von wx orientieren soll...)
Eigentlich ist es Geschmackssache, so gefällt es mir aber recht gut. Naja... ich schau noch, wie ich das mache. Dynamisch ist für mich immer besser als redundant. Die restlichen Widgets werde ich wohl dann auch so ähnlich erstellen, damit komm ich dann besser zurecht.
Vielen dank für die zahlreichen Ratschläge
(Bin offen für weiteres, keine Frage!)
das Frame war nur'n Beispiel, ich hab den richtigen Namen rausgelöscht, weil ich das für'n Projekt für mein Praktikum machen, Datenschutz etc... Also, in einem wirklichen Frame würde ich den Namen eher weniger benutzen. Ich arbeite momentan das Buch "wxPython in Action" durch und da stehen halt diese Empfehlungen, dass man diese Argumente benutzen soll und sowas. Also, dass man pos, size und so weiter überhaupt nicht braucht, wusste ich gar nicht. Deswegen bin ich dir für diesen Ratschlag überaus dankbar!
Die Sache mit dem Menu und Binding hatte ich bereits vorhin geändert, nachdem ich einen Gedanken daran verschwendet habe, hab ich mir gedacht: "Hmpf oO' einfach nur Menu ist unklug." Aber trotzdem danke. Ich benutze keine Unterstriche, weil ich gern in wxPython Programmen deren Konvention behalten möchte. Aber darüber denke ich nochmal nach

Zu deiner persönliche Vorliebe: Ich hab einen tollen Codesnippet im Buch gefunden, der die Teiel sozusagen "dynamisch" erstellt und das ganze ohne redundanzen wesentlich flüssiger und schöner für mich darstellt. Der Codesnippet ist fast komplett aus dem Buch übernommen!
Code ausgelagert...
(In dem Code hab ich jetzt die Namenskonventionen gemischt, dass ist mir klar. Ich bin mir noch nicht sicher, wie ich es genau mache :/ Ich tendiere aber natürlich zu PEP8, obwohl wxPython sagt, dass man sich an der Namenskonvention von wx orientieren soll...)
Eigentlich ist es Geschmackssache, so gefällt es mir aber recht gut. Naja... ich schau noch, wie ich das mache. Dynamisch ist für mich immer besser als redundant. Die restlichen Widgets werde ich wohl dann auch so ähnlich erstellen, damit komm ich dann besser zurecht.
Vielen dank für die zahlreichen Ratschläge

- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo BlackVivi!BlackVivi hat geschrieben:Ich tendiere aber natürlich zu PEP8, obwohl wxPython sagt, dass man sich an der Namenskonvention von wx orientieren soll...
- Wenn du dich an PEP8 hälst, dann gibt es keine ungewünschten Namensüberschneidungen. Z.B.: "close" überschreibt nicht die eingebaute Methode "Close". "on_close" überschreibt nicht "OnClose". So können weniger unerklärliche Fehler passieren.
- wxWidgets ist in C++ geschrieben. Dort werden die Namen groß/klein geschrieben. Der Entwickler von wxPython kommt auch aus der C++-Schiene. Niemand erwartet, dass er ständig umdenken muss. Und dass seine Empfehlung "groß/klein" lautet, verwundert mich auch nicht.
- Ich halte mich an die Empfehlung für Python-Programme.
- Wenn du eine Erweitung für wxPython schreiben möchtest, dann musst du dich dabei an die Forderung von Dunn halten. Wenn nicht, dann wird er deinen Code nicht in wxPython integrieren. Sonst gibt es keinen Grund dafür.
Wenn ich etwas hasse, dann das Mischen der Namenskonventionen. Warum soll ich beim Schreiben von Python-Programmen, zwei Konventionen benutzen und im Kopf behalten müssen, welche Methode nun klein und welche groß/klein geschrieben wurde... :K
Das ist gleich wie bei JavaScript. "innerHTML" und "getElementById" sind so typische Negativbeispiele für diese Schreibweise. Warum wird ID nicht auch komplett groß geschrieben? Warum wird HTML groß geschrieben? (innerHtml) So muss ich mir nicht nur den Namen, sondern auch noch die exakte Schreibweise des Befehls merken! Nicht mir mir! Nicht bei meinem miesen Gedächtnis. "inner_html" und "get_element_by_id" --> Da müsste ich mir nur den Namen bzw. die Worte merken, aus denen der Befehl besteht. Aber warum einfach, wenn es kompliziert auch geht?
lg
Gerold

http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Hoi,
ich bevorzuge eher diese Variante: http://www.python-forum.de/topic-6891.html
D. h. auslagern des Codes für best. Elemente, wie Menüs, Buttons des Hauptframes, usw. in Extramodule, die möglichst übersichtlich gestaltet werden.
Gleich drei Funktionen zur Menubar im Hauptframe zu haben, finde ich - wegen der Verschachtelung -- eher unübersichtlich. Man muß ja ständig suchen in welcher Funktion welche Funktionalität ist. Insbesondere bei größeren Projekten wird das schnell unübersichtlich.
Gruß,
Christian
PS Sorry für die Eigenwerbung
ich bevorzuge eher diese Variante: http://www.python-forum.de/topic-6891.html
D. h. auslagern des Codes für best. Elemente, wie Menüs, Buttons des Hauptframes, usw. in Extramodule, die möglichst übersichtlich gestaltet werden.
Gleich drei Funktionen zur Menubar im Hauptframe zu haben, finde ich - wegen der Verschachtelung -- eher unübersichtlich. Man muß ja ständig suchen in welcher Funktion welche Funktionalität ist. Insbesondere bei größeren Projekten wird das schnell unübersichtlich.
Gruß,
Christian
PS Sorry für die Eigenwerbung

Hallöschen Gerold ^_^,
fantastische Argumente, alle ersichtlich. Noch mehr Gründe zu pep8 zu tendieren, ich denke ich werde den Ratschlag aus wxPython in Action einfach übergehen und wirklich für Funktionen lowercase_with_underscores benutzen usw...
Du wolltest du mir noch ein Beispiel geben, ich hoffe das machst du noch, ich würde mich sehr freuen.
@CM
Dein Beispiel sieht sehr schick aus und ist auch recht logisch gecoded. Aber für mein Projekt ist es doch wohl zu unübersichtlich. 3 Funktionen zu benutzen für die Menubar erscheint etwas viel, aber es ist ja klar ersichtlich, was jeder Teil tut, zumindest für mich. Ich will jetzt nicht dein Beispiel runter machen oder meins zum absolut tollsten machen, immerhin stammt es nicht einmal von mir, aber das ganze so auszulagern find ich doch für mich etwas zu krass. Bei mir seh ich sofort welche Menüpunkte es gibt und dank der Einrückung auch was wozu gehört. Toll außerdem, das ich direkt das Binding dazuschreib.
Also tendiere ich eher zu Gerolds Vorschlag (bei so wenig Menüpunkten, es im _init_ einfach zu halten) oder eben das was ich jetzt habe, immerhin macht es das erweitern relativ einfach.
Nochmals danke für die Hilfe
Vielleicht bau ich das nochmal auf 2 Funktionen um und versuch nochmal bessere namen zu finden für die Variablen.
fantastische Argumente, alle ersichtlich. Noch mehr Gründe zu pep8 zu tendieren, ich denke ich werde den Ratschlag aus wxPython in Action einfach übergehen und wirklich für Funktionen lowercase_with_underscores benutzen usw...
Du wolltest du mir noch ein Beispiel geben, ich hoffe das machst du noch, ich würde mich sehr freuen.
@CM
Dein Beispiel sieht sehr schick aus und ist auch recht logisch gecoded. Aber für mein Projekt ist es doch wohl zu unübersichtlich. 3 Funktionen zu benutzen für die Menubar erscheint etwas viel, aber es ist ja klar ersichtlich, was jeder Teil tut, zumindest für mich. Ich will jetzt nicht dein Beispiel runter machen oder meins zum absolut tollsten machen, immerhin stammt es nicht einmal von mir, aber das ganze so auszulagern find ich doch für mich etwas zu krass. Bei mir seh ich sofort welche Menüpunkte es gibt und dank der Einrückung auch was wozu gehört. Toll außerdem, das ich direkt das Binding dazuschreib.
Also tendiere ich eher zu Gerolds Vorschlag (bei so wenig Menüpunkten, es im _init_ einfach zu halten) oder eben das was ich jetzt habe, immerhin macht es das erweitern relativ einfach.
Nochmals danke für die Hilfe

BlackVivi, hast schon recht, wenn Du die Vor- und Nachteile abgwiegst, wie Du's machst, aber hierzu
GUIs tendieren dazu rel. viel Codezeilen zu provozieren. Und so kommt es, daß auch in Projekten von halbwegs moderater Größe leicht einige tausend Zeilen mehr oder weniger direkt mit dem Mainframe verbunden sein können. (Und ich bemühe mich kurz zu schreiben
.) Ohne Auslagerung ist das nicht zu machen. So hat man in __init__ eine importierte Funktion,die einmal aufgerufen wird und bei der klar ist, was sie macht und wo man sie findet - und der Mainframe bleibt in einer Datei, die nicht allzu aufgeblasen ist.
Gruß,
Christian
noch eine Randnotiz:BlackVivi hat geschrieben: aber das ganze so auszulagern find ich doch für mich etwas zu krass.
GUIs tendieren dazu rel. viel Codezeilen zu provozieren. Und so kommt es, daß auch in Projekten von halbwegs moderater Größe leicht einige tausend Zeilen mehr oder weniger direkt mit dem Mainframe verbunden sein können. (Und ich bemühe mich kurz zu schreiben

Gruß,
Christian
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo BlackVivi!BlackVivi hat geschrieben:Der Codesnippet ist fast komplett aus dem Buch übernommen! Code ausgelagert...
Das betrifft jetzt nur die Menüerstellung.
Hier bleibt es wohl dem Programmierer überlassen. Das Beispiel oben ist nicht schlecht. Hier überwiegen eher die persönlichen Vorlieben.
Das hier habe ich einfach so, ohne irgendwo nachsehen zu müssen, hingeschrieben. Es ist also, nur für mich persönlich, die einfachere Variante.:
http://paste.pocoo.org/show/9114/
Wenn ich die in deinem Beispiel gezeigten Funktionen nicht irgendwoher kopieren kann, dann bin ich mit meinem Beispiel sicher schneller -- da ich es nicht mehr entwickeln muss.
Wie schon geschrieben. Hier entscheidet eher die Vorliebe des Programmierers.

mfg
Gerold

Zuletzt geändert von gerold am Montag 5. November 2007, 16:30, insgesamt 2-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
@CM
Das ist ein sehr greifendes Argument, wie oft hab ich schon durch Quelltexte gesehen und nicht direkt gefunden, wo das erstellt wird usw. Aber ich sehe hier einen direkten Unterschied zwischen Gerold und dir:
Gerold: "So offensichtliche Sachen muss man so schnell wie möglich finden, Redundanz wird einfach "weggescrollt". Sowas entwickelt sich schneller und ist im Notfall auch leichter zu entwirren.
CM: "Menübars oder Statusbars müssen offensichtlich getrennt werden vom Frame, da sonst das wesentliche nicht mehr so in's Auge fällt. Ich sehe: "Aha, das importierte Modul macht die Menübar" und schon öffne ich die und hab den ganzen Code."
Beide Varianten sind für mich super, wenn ich ehrlich bin. Und im Moment mach ich'n Zwischending, finde ich. Aber naja,.... Ich werd einfach noch weiter entwickeln und wenn ich merke: "Ach Mist, ich scroll und such mich zu tode"... dann weiß ich ja, dass ich was ändern muss. Aber vielen Dank! Ich komm nochmal drauf zurück. Der Faden ist bestimmt auch hilfreich für die meisten anderen WX Programmierer...
(Nochmal ohne Namensmist)
Das ist ein sehr greifendes Argument, wie oft hab ich schon durch Quelltexte gesehen und nicht direkt gefunden, wo das erstellt wird usw. Aber ich sehe hier einen direkten Unterschied zwischen Gerold und dir:
Gerold: "So offensichtliche Sachen muss man so schnell wie möglich finden, Redundanz wird einfach "weggescrollt". Sowas entwickelt sich schneller und ist im Notfall auch leichter zu entwirren.
CM: "Menübars oder Statusbars müssen offensichtlich getrennt werden vom Frame, da sonst das wesentliche nicht mehr so in's Auge fällt. Ich sehe: "Aha, das importierte Modul macht die Menübar" und schon öffne ich die und hab den ganzen Code."
Beide Varianten sind für mich super, wenn ich ehrlich bin. Und im Moment mach ich'n Zwischending, finde ich. Aber naja,.... Ich werd einfach noch weiter entwickeln und wenn ich merke: "Ach Mist, ich scroll und such mich zu tode"... dann weiß ich ja, dass ich was ändern muss. Aber vielen Dank! Ich komm nochmal drauf zurück. Der Faden ist bestimmt auch hilfreich für die meisten anderen WX Programmierer...
(Nochmal ohne Namensmist)
Ja, BlackVivi, mit Deiner Beschreibung triffst Du den Nagel auf den Kopf. Und ich habe mir gerade Gerolds Beispiel angeschaut und gedacht: "Nee, bloß nicht!"
-- ist eben doch Geschmackssache. Auf "meine" Variante bin ich auch erst verfallen, als bei mir erste Probleme wegen Unübersichtlichkeit aufkamen. Bei kleinen GUIs spielt das wohl gar keine Rolle. (Inzwischen ist bei mir daheim der Code auch PEP8-konform *hust*)
Gruß,
Christian

Gruß,
Christian
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo BlackVivi!gerold hat geschrieben:Ein Frame bekommt bei mir immer eine eigene Klasse. Oft verwende ich für Panels, mit vielen Widgets oder einer eigenständigen Funktion, ebenfalls eigene Klassen. Also immer dann, wenn etwas gut abgetrennt werden kann (z.B. die Panels, die in ein Notebook gelegt werden), dann bekommt es eine eigene Klasse spendiert. Ich schreibe dir dafür noch ein kleines Beispiel.
Ich bin mir im Moment nur nicht so sicher, ob dir dieses Beispiel jetzt schon etwas bringen wird. Außerdem habe ich jetzt nicht sonderlich auf Sauberkeit und Kommentare geachtet. :K
http://paste.pocoo.org/show/9123/
Ich habe das Grundgerüst aus http://www.python-forum.de/topic-5722.html und die Events aus http://www.python-forum.de/topic-9977.html genommen und leicht angepasst.
Wenn es dir nichts bringt oder du einfach noch nicht damit klar kommst -- einfach ignorieren und vergessen.
mfg
Gerold

http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Dankeschön Geroldgerold hat geschrieben:http://paste.pocoo.org/show/9123/
Ich habe das Grundgerüst aus http://www.python-forum.de/topic-5722.html und die Events aus http://www.python-forum.de/topic-9977.html genommen und leicht angepasst.
Wenn es dir nichts bringt oder du einfach noch nicht damit klar kommst -- einfach ignorieren und vergessen.
mfg
Gerold

Ich glaube, ich werde mal eine Seite in's Wiki schreiben mit dem Thema und den ganzen Codesnippets hier und auch die Sache mit den Namenskonvention. Ich denke, dass könnte ganz interessant sein.
Ihr seid die besten, und auch nochmal ein spezielles dank an CM und Gerold
