
Hi Liste, ich hab irgendwo mal was über getter/setter für Python-Klassen gelesen. Irgendwie konnte man instanz.variable = "foo" machen und intern wurde aber eine Setterfunktion aufgerufen. Sowas könnte ich jetzt gut gebrauchen. Weis jemand wie das nochmal ging, bzw. wo ich das nachlesen kann? Ich glaube es hatte irgendwas mit Decorators zu tun, mit denen hab ich aber bisher noch nie gearbeitet. Falls es jemanden interessiert warum ich das brauche: Ich hab eine Klasse mit einer __str__-Funktion von der ich annehme das sie recht teuer ist, da sie einen formatierten String zurück gibt in denen fast jede Klassenvariable einmal vorkommt. Diese Funktion wird extrem häufig aufgerufen und da habe ich mir überlegt, dass es einfacher ist den String einmal zu generieren und dann zwischenzuspeichern um ihn direkt zurückzugeben anstatt ihn jedes mal zu generieren. Da der String stets aktuell sein muss, müsste er bei jeder Änderung einer Klassenvariable neu generiert werden. Schöne Grüße, Bastian -- Bastian Venthur http://venthur.de Debian Developer venthur at debian org

--On 18. Juli 2007 12:04:53 +0200 Bastian Venthur <venthur@debian.org> wrote:
Hi Liste,
ich hab irgendwo mal was über getter/setter für Python-Klassen gelesen. Irgendwie konnte man
instanz.variable = "foo"
machen und intern wurde aber eine Setterfunktion aufgerufen. Sowas könnte ich jetzt gut gebrauchen. Weis jemand wie das nochmal ging, bzw. wo ich das nachlesen kann? Ich glaube es hatte irgendwas mit Decorators zu tun, mit denen hab ich aber bisher noch nie gearbeitet.
"Python Properties" sind Deine magischen Suchbegriffe: <http://www.python.org/download/releases/2.2/descrintro/#property> <http://blog.ianbicking.org/property-decorator.html> -aj

On 18.07.2007 12:09 schrieb Andreas Jung:
--On 18. Juli 2007 12:04:53 +0200 Bastian Venthur <venthur@debian.org> wrote:
ich hab irgendwo mal was über getter/setter für Python-Klassen gelesen. Irgendwie konnte man
instanz.variable = "foo"
machen und intern wurde aber eine Setterfunktion aufgerufen. Sowas könnte ich jetzt gut gebrauchen. Weis jemand wie das nochmal ging, bzw. wo ich das nachlesen kann? Ich glaube es hatte irgendwas mit Decorators zu tun, mit denen hab ich aber bisher noch nie gearbeitet.
"Python Properties" sind Deine magischen Suchbegriffe:
Danke, properties hab ich gesucht. Da ich aber ziemlich viele Klassenvariablen habe würde diese Lösung meine Klasse allerdings unnötig aufblähen. Eigentlich würde ich beim setzen (irgend)einer Klassenvariable nur eine Variable "dirty" auf False setzen wollen und bei der __str__-Methode je nach dirtyness entscheiden ob ich einen zuvor generierten string zurückgebe oder neu generieren muss: def __str__(self): if not self.dirty: return self.s else: self.s = some_complicated_method_returning_a_string() self.dirty = false return self.s Gibt es ne Möglichkeit bei jedem Schreibzugriff auf eine Klassenvariable eine bestimmte Funktion auszuführen? Schöne Grüße, Bastian -- Bastian Venthur http://venthur.de Debian Developer venthur at debian org

--On 18. Juli 2007 12:39:52 +0200 Bastian Venthur <venthur@debian.org> wrote:
On 18.07.2007 12:09 schrieb Andreas Jung:
--On 18. Juli 2007 12:04:53 +0200 Bastian Venthur <venthur@debian.org> wrote:
ich hab irgendwo mal was über getter/setter für Python-Klassen gelesen. Irgendwie konnte man
instanz.variable = "foo"
machen und intern wurde aber eine Setterfunktion aufgerufen. Sowas könnte ich jetzt gut gebrauchen. Weis jemand wie das nochmal ging, bzw. wo ich das nachlesen kann? Ich glaube es hatte irgendwas mit Decorators zu tun, mit denen hab ich aber bisher noch nie gearbeitet.
"Python Properties" sind Deine magischen Suchbegriffe:
Danke, properties hab ich gesucht. Da ich aber ziemlich viele Klassenvariablen habe würde diese Lösung meine Klasse allerdings unnötig aufblähen.
Gibt es ne Möglichkeit bei jedem Schreibzugriff auf eine Klassenvariable eine bestimmte Funktion auszuführen?
__getattr__() überschreiben. -aj

Bastian Venthur:
Gibt es ne Möglichkeit bei jedem Schreibzugriff auf eine Klassenvariable eine bestimmte Funktion auszuführen?
Ja, das wollte ich eh schon vorschlagen: <http://docs.python.org/ref/new-style-attribute-access.html>. Man muss aber etwas aufpassen, sich damit nicht in den Fuss zu schießen. J. -- When I am doing sex I wonder if my emotions can be detected by alien civilisations. [Agree] [Disagree] <http://www.slowlydownward.com/NODATA/data_enter2.html>

Hallo! Bastian Venthur wrote:
On 18.07.2007 12:09 schrieb Andreas Jung:
--On 18. Juli 2007 12:04:53 +0200 Bastian Venthur <venthur@debian.org> wrote:
ich hab irgendwo mal was über getter/setter für Python-Klassen gelesen. Irgendwie konnte man
instanz.variable = "foo"
machen und intern wurde aber eine Setterfunktion aufgerufen. Sowas könnte ich jetzt gut gebrauchen. Weis jemand wie das nochmal ging, bzw. wo ich das nachlesen kann? Ich glaube es hatte irgendwas mit Decorators zu tun, mit denen hab ich aber bisher noch nie gearbeitet. "Python Properties" sind Deine magischen Suchbegriffe:
Danke, properties hab ich gesucht. Da ich aber ziemlich viele Klassenvariablen habe würde diese Lösung meine Klasse allerdings unnötig aufblähen.
Eigentlich würde ich beim setzen (irgend)einer Klassenvariable nur eine Variable "dirty" auf False setzen wollen und bei der __str__-Methode je nach dirtyness entscheiden ob ich einen zuvor generierten string zurückgebe oder neu generieren muss:
def __str__(self): if not self.dirty: return self.s else: self.s = some_complicated_method_returning_a_string() self.dirty = false return self.s
Gibt es ne Möglichkeit bei jedem Schreibzugriff auf eine Klassenvariable eine bestimmte Funktion auszuführen?
Such mal nach dem "memoize" pattern, ich glaube, das ist das, was du in Wirklichkeit suchst. Stefan

On Wednesday 18 July 2007 12:04, Bastian Venthur wrote:
Hi Liste,
ich hab irgendwo mal was über getter/setter für Python-Klassen gelesen. Irgendwie konnte man
instanz.variable = "foo"
machen und intern wurde aber eine Setterfunktion aufgerufen. Sowas könnte ich jetzt gut gebrauchen. Weis jemand wie das nochmal ging, bzw. wo ich das nachlesen kann? Ich glaube es hatte irgendwas mit Decorators zu tun, mit denen hab ich aber bisher noch nie gearbeitet.
Falls es jemanden interessiert warum ich das brauche: Ich hab eine Klasse mit einer __str__-Funktion von der ich annehme das sie recht teuer ist, da sie einen formatierten String zurück gibt in denen fast jede Klassenvariable einmal vorkommt. Diese Funktion wird extrem häufig aufgerufen und da habe ich mir überlegt, dass es einfacher ist den String einmal zu generieren und dann zwischenzuspeichern um ihn direkt zurückzugeben anstatt ihn jedes mal zu generieren. Da der String stets aktuell sein muss, müsste er bei jeder Änderung einer Klassenvariable neu generiert werden.
Andreas hat die richtige Antwort gegeben bzgl. deiner Ursprungsfrage - wie man properties macht. Aber dein Usecase ist in diesem Fall IMHO nicht geeignet. Denn letztlich machst du dir sehr, sehr viel arbeit auf die Weise. Stattdessen solltest mit __getattr__/__setattr__ arbeiten. Damit kannst du ein dirty-flag setzten wann immer du einen Wert setzt - und daraufhin dein gecachten String neu rendern. In etwa so (aussem Kopp): class Foo(object): def __init__(self): d = self.__dict__ # das brauchn wir, weil __setattr__ ueberladen ist d['_dirty'] = True # ab jetzt ist alles ok... self.foo = "bar" def __getattr__(self, name): return self.__dict__[name] def __setattr__(self, name, value): self._dirty = True self.__dict__[name] = value def __str__(self): if self._dirty: self._str = berechne_str() self._dirty = False return self._str Diez

Danke, die Tipps mit property und get/setattr haben geholfen. Allerdings hat meine Grundidee nicht funktioniert. Das cachen meines Strings brachte keine Geschwindigkeitsvorteile. Endweder war mein String nicht kompliziert genug, oder Python macht das sehr effizient (vermutlich cacht es selbst im Hintergrund, anders kann ich mir die exakt gleichen Geschwindigkeiten in beiden Varianten nicht erklären). Danke und Schöne Grüße, Bastian -- Bastian Venthur http://venthur.de Debian Developer venthur at debian org

On Wednesday 18 July 2007 13:10, Bastian Venthur wrote:
Danke, die Tipps mit property und get/setattr haben geholfen. Allerdings hat meine Grundidee nicht funktioniert. Das cachen meines Strings brachte keine Geschwindigkeitsvorteile. Endweder war mein String nicht kompliziert genug, oder Python macht das sehr effizient (vermutlich cacht es selbst im Hintergrund, anders kann ich mir die exakt gleichen Geschwindigkeiten in beiden Varianten nicht erklären).
Das tut es ganz bestimmt nicht. Python ist als seiteneffekt-beladene Sprache nicht in der Lage, sowas automatisch zu machen. Im Zweifelsfall geht dein String-bauen im "Rauschen" unter. Diez

Hallo Bastian, On 2007-07-18 13:10, Bastian Venthur wrote:
Danke, die Tipps mit property und get/setattr haben geholfen. Allerdings hat meine Grundidee nicht funktioniert. Das cachen meines Strings brachte keine Geschwindigkeitsvorteile.
ich hätte dir auch empfohlen, zuerst mal zu messen, ob dein Code wirklich zu langsam ist. Ich glaube, die meisten "Optimierungen", die vorsorglich nach dem Motto "Das wird bestimmt zu langsam sein" vorgenommen werden, bringen so gut wie gar nichts. Und viele, die überhaupt einen messbaren Effekt haben, fallen beim normalen Gebrauch der Software gar nicht auf. Leseempfehlungen: http://www.martinfowler.com/ieeeSoftware/yetOptimization.pdf http://sschwarzer.com/download/optimization_europython2006.pdf Viele Grüße Stefan
participants (6)
-
Andreas Jung
-
Bastian Venthur
-
Diez B. Roggisch
-
Jochen Schulz
-
Stefan Behnel
-
Stefan Schwarzer