Frage

Ich habe mit pygame und Python rumgespielt und ich möchte in der Lage sein, eine Funktion aufzurufen, wenn ein Attribut meiner Klasse geändert hat. Meine aktuelle Lösung Wesen:

class ExampleClass(parentClass):
   def __init__(self):
      self.rect = pygame.rect.Rect(0,0,100,100)
   def __setattr__(self, name, value):
      parentClass.__setattr__(self,name,value)
      dofancystuff()
Firstclass = ExampleClass()

Das funktioniert gut und dofancystuff aufgerufen wird, wenn ich den rect Wert mit Firsclass.rect = pygame.rect.Rect(0,0,100,100) ändern. Allerdings, wenn ich sage, Firstclass.rect.bottom = 3. __setattr__ und dort für dofancystuff nicht aufgerufen wird.

Also meine Frage, die ich denke, ist, wie kann ich abfangen jede Änderung an einem Attribut einer Unterklasse?

edit: Auch wenn ich über das der falsche Weg, bitte werde ich sagen, ich bin nicht sehr kenntnisreich, wenn es um Python kommt

.
War es hilfreich?

Lösung

Nun, die einfache Antwort ist, kann man nicht. Im Fall von Firstclass.rect = <...> ist Ihr __setattr__ genannt. Aber im Fall von Firstclass.rect.bottom = 3 die __setattr__ Methode der Rect-Instanz aufgerufen wird. Die einzige Lösung, die ich sehe, ist eine abgeleitete Klasse von pygame.rect.Rect zu schaffen, in dem Sie die __setattr__ Methode überschreiben. Sie können auch die Rect Klasse Affe Patch, aber dies ist aus guten Gründen abgeraten.

Andere Tipps

Sie könnten versuchen, __getattr__, die auf Firstclass.rect aufgerufen werden soll.

Aber tun Sie stattdessen: Erstellen Sie eine separate Klasse (Unterklasse von pygame.rect?) Für ExampleClass.rect. Implementieren __setattr__ in dieser Klasse. Nun werden Sie über alles gesagt, dass für rect in Ihrem ExampleClass Mitglied gesetzt wird. Sie können immer noch __setattr__ in ExampleClass implementieren (und sollte ), erst jetzt stellen Sie sicher, eine Version Ihrer eigenen rect Klasse instanziiert ...

BTW: Rufen Sie nicht Ihre Objekte Firstclass, wie dann sieht es aus wie eine Klasse, die als Gegensatz zu einem Objekt ...

Das ist die Frage nicht beantworten, aber es ist relevant:

self.__dict__[name] = value

ist wahrscheinlich besser als

parentClass.__setattr__(self, name, value)

Dies wird durch die Python-Dokumentation empfohlen (setattr "> http://docs.python.org/2/reference/datamodel.html?highlight=setattr#object. setattr ) und macht mehr Sinn ohnehin im allgemeinen Fall, da sie davon ausgehen, nichts über das Verhalten von Parent setattr .

Yay für ungebetene Ratschläge 4 Jahre zu spät!

Ich denke, der Grund, warum Sie diese Schwierigkeiten haben, ein wenig mehr Informationen verdient, als von den anderen Antworten zur Verfügung gestellt wird.

Das Problem ist, wenn Sie das tun:

myObject.attribute.thing = value

Sie Zuordnung keinen Wert zuzuschreiben. Der Code entspricht dies:

anAttribute = myObject.attribute
anAttribute.thing = value

Wie es von myObject gesehen hat, alles, was Sie tun es das Attribut bekommen; Sie sind nicht das Attribut festlegen.

Erstellen Subklassen Ihrer Attribute, die Sie steuern und definieren __setattr__ kann für eine Lösung ist.

Eine alternative Lösung, die Sinn machen, wenn Sie viele Attribute verschiedener Typen haben und wollen nicht viele einzelne Unterklassen für alle von ihnen machen, ist __getattribute__ oder __getattr__ außer Kraft zu setzen eine Fassade auf das Attribut zurückzuversetzen führt die entsprechenden Operationen in seiner __setattr__ Methode. Ich habe nicht zu tun dies selbst versucht, aber ich kann mir vorstellen, dass Sie in der Lage sein sollte, eine einfache Fassade Klasse zu machen, die für jedes Objekt als Fassade dienen soll.

Pflege müssten bei der Wahl der __getattribute__ und __getattr__ . Siehe die im vorhergehenden Satz verknüpft Dokumentation für Informationen, aber im Grunde, wenn __getattr__ verwendet wird, haben die aktuellen Attribute oben gekapselt sein / verschleierten irgendwie so dass __getattr__ Anfragen für sie behandelt, und wenn __getattribute__ verwendet wird, wird es haben Attribute abrufen über Anrufe an eine Basisklasse.

Wenn alle Sie versuchen zu tun, ist festzustellen, ob einige Rects aktualisiert wurden, dann ist dies viel des Guten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top