3

私はpygameとpythonをいじっていますが、クラスの属性が変更されたときに関数を呼び出せるようにしたいと思っています。私の現在の解決策は次のとおりです。

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()

これは正常に機能し、rect値を。で変更するとdofancystuffが呼び出されますFirsclass.rect = pygame.rect.Rect(0,0,100,100)。しかし、私が言うならFirstclass.rect.bottom = 3__setattr__そして、dofancystuffは呼び出されません。

だから私の質問は、サブクラスの属性への変更をどのようにインターセプトできるかということです。

編集:また、私がこれについて間違った方法で行っている場合は、Pythonに関してはあまり知識がないことを伝えてください。

4

4 に答える 4

4

まあ、簡単な答えはあなたができないということです。Firstclass.rect = <...>あなたの場合__setattr__はと呼ばれます。しかし、RectインスタンスFirstclass.rect.bottom = 3のメソッドの場合は呼び出されます。__setattr__私が見る唯一の解決策は、メソッドを上書きするpygame.rect.Rectの派生クラスを作成することです__setattr__。Rectクラスにモンキーパッチを適用することもできますが、これは正当な理由からお勧めできません。

于 2009-03-24T10:46:29.483 に答える
1

を試すことができます。__getattr__これはで呼び出す必要がありますFirstclass.rect

ただし、代わりにこれを行ってください。の別のクラス(pygame.rect?のサブクラス)を作成しますExampleClass.rect__setattr__そのクラスで実装します。rectこれで、メンバーに設定されるすべての情報が通知されますExampleClass。あなたはまだで実装することができます__setattr__ExampleClassそしてそうすべきです)、今だけあなたがあなた自身のrectクラスのバージョンをインスタンス化することを確認してください...

ところで:オブジェクトを呼び出さないでください。オブジェクトFirstclassではなくクラスのように見えます...

于 2009-03-24T10:39:20.390 に答える
0

あなたがこの困難を抱えている理由は、他の回答で提供されるよりももう少し多くの情報に値すると思います.

問題は、次の場合です。

myObject.attribute.thing = value

属性に値を割り当てていません。コードはこれと同等です:

anAttribute = myObject.attribute
anAttribute.thing = value

myObject からわかるように、属性を取得するだけです。属性を設定していません。

あなたが制御し、 __setattr__ を定義できる属性のサブクラスを作成することは、1 つの解決策です。

さまざまなタイプの属性が多数あり、それらすべてに対して個別のサブクラスを多数作成したくない場合に役立つ代替ソリューションは、 __getattribute__ または __getattr__ をオーバーライドして、関連する処理を実行する属性にファサードを返すことです。 __setattr__ メソッドでの操作。私はこれを自分でやろうとしたことはありませんが、任意のオブジェクトのファサードとして機能する単純なファサード クラスを作成できるはずだと思います。

__getattribute____getattr__の選択には注意が必要です。詳細については、前の文にリンクされているドキュメントを参照してください。ただし、基本的に __getattr__ が使用されている場合、実際の属性は何らかの形でカプセル化/難読化されているため、__getattr__ はそれらのリクエストを処理し、__getattribute__ が使用されている場合は、属性を取得する必要があります。基本クラスへの呼び出しを介して。

いくつかの四角形が更新されているかどうかを判断することだけが目的である場合、これはやり過ぎです。

于 2009-07-11T01:07:07.823 に答える