miriki: was hast du denn letztendlich vor? Getter und Setter sind in Python unüblich (und in der Regel überflüssig), weil es durch die Bank direkten Zugriff auf Attribut gibt. Warum hast du zwei Underscores vor dem Funktionsnamen?
Deine zweite Frage ist recht gut hier beantwortet, bevor ich das selbst versuche, zusammenzufassen.
Setter / Getter benutze ich prinzipiell gerne, vor allem sicherlich auch, weil ich diese Kapselung von anderen Sprachen her einfach gewohnt bin. Es ist aber auch die Kontrolle über die Werte, die ich gerne behalten will. So wird ein Setter gern mal den Werte-Bereich im Auge behalten. Außerdem sind ggf. nach dem Setzen eines Wertes unverzüglich weitere Aktionen notwendig. Eine andere Möglichkeit, auf Veränderung der Attribute zu reagieren, habe ich ja nicht, oder?
Außerdem möchte ich ungern direkten Zugriff auf gespeicherte sensible Daten (z.B. Paßwort) zulassen - "write-only" nur per Setter ohne Getter. Und es macht auch keinen Sinn, den Temperatur-Wert eines Sensors zu setzen - da macht "read-only" über nur den Getter alleine Sinn. Ja, ich weiß... Auch mit __ läßt sich das alles nur mehr oder weniger stark verschleiern und letztendlich auch umgehen. Aber wenn ich mein Schlüsselbund in meinen Briefkasten werfe, tue ich das absichtlich und bin selbst schuld für die Folgen.
Hier konkret in diesem Beispiel: mein von ttk.Button abgeleiteter mrk.Button bekommt das neue Attribut "imgfile", in dem ein Dateiname zu einem Bild gespeichert wird. Wenn jetzt ein Dateiname gesetzt wird, dann überprüft der Setter ggf., ob die Datei existiert, ein gültiges Bild ist usw. und setzt ansonsten "None" als Wert, bevor mir nachgeschaltete Routinen unkontrolliert gegen die Wand fahren. (Ja, eine Warnung gebe ich vielleicht zusätzlich auch noch aus...)
Die könnten natürlich auch alle jeweils jedesmal auf die Existenz / Gültigkeit der Datei prüfen, aber wenn dies in einer Timer-Loop jede Sekunde passiert, killt das die Performance ohne Ende. Da teste ich doch lieber schnell mal auf imgfile != None und verlaß mich ansonsten darauf, daß eine vorgeschaltete Routine (eben dieser Setter) einmal überprüft hat, daß es ein Bild ist, daß ich verarbeiten kann.
Und wenn ein neuer Dateiname gesetzt wird, dann soll das Bild auch sofort aktualisiert werden, und nicht erst, wenn das nächste Event (Timer, Interrupt, wasauchimmer...) eintritt.
Aus Performance-Gründen speichere ich das geladene Bild auch intern. Das Bild soll nämlich dynamisch an die Größe des Buttons angepaßt werden. Da will ich aber nicht bei jeder Größenänderung das Bild (von Platte, Netz, Staffelei
...) neu laden.
Deswegen habe ich
- property imgfile --> Setter/Getter für self.__imgfile
- self.__imgfile --> Dateiname
- self.__bitmap --> Image.open( self.__imgfile )
- self.__image --> ImageTk.PhotoImage( self.__bitmap )
- self.onConfigure() --> setzt self['image'] = self.__image nach Anpassung
Gruß, Michael