2009-03-24 16 views
3

私はpygameとpythonを使いこなしています。クラスの属性が変更されたときに関数を呼び出せるようにしたいと考えています。私の現在のソリューション・ビーイング:クラス内のクラスの属性の変更を傍受する - 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() 

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

だから私の推測では、サブクラスの属性の変更をどのように傍受できますか?

編集:もし私がこれを間違った方法で行っているのであれば、私はそれがPythonに関してはあまり知られていないと教えてください。

+0

AFAIK pdbはこの機能をまだサポートしていません。 – hochl

答えて

4

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

+0

+1:独自の四角形のサブクラスを作成し、すべてのものに使用します。 –

1

__getattr__を試すと、Firstclass.rectで呼び出す必要があります。

代わりにこれを実行します。ExampleClass.rectの別のクラス(pygame.rectのサブクラス)を作成します。そのクラスに__setattr__を実装します。今度はあなたのrectメンバーにExampleClassのために設定されているものについて話されます。あなたはまだExampleClass__setattr__を実装(およびべき)することができ、今だけところで...

をあなた自身rectクラスのバージョンをインスタンス化してください:それはのように見えるよう、Firstclassあなたのオブジェクトを呼び出すことはありません。クラスとは対照的にオブジェクトです...

0

私はこの難しさを持っている理由は、他の答えよりも少し情報が必要だと思います。

問題は、あなたが行う場合は、次のとおりです。

myObject.attribute.thing = value 

あなたは属性に値を代入していません。コードは次のようになります。

anAttribute = myObject.attribute 
anAttribute.thing = value 

これはmyObjectから見れば分かりませんが、属性を取得しています。属性を設定していません。

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

異なるタイプの属性が多く、個々のサブクラスをたくさん作成したくない場合は、__getattribute__または__getattr__をオーバーライドして属性のファサードを返すこともできますその__setattr__メソッドで関連する操作を実行します。私はこれを自分でやろうとはしませんでしたが、どのオブジェクトのファサードとしても機能する簡単なファサードクラスを作ることができるはずです。

ケアは、__getattribute____getattr__の中から選択する必要があります。前の文でリンクされているドキュメントを参照してください。しかし、__getattr__が使用されている場合、__getattr__が要求を処理するように実際の属性がカプセル化/難読化されます。__getattribute__が使用されている場合、ベースクラスへの呼び出しを介して。

あなたがしようとしているのは、いくつかの矩形が更新されているかどうかを判断することだけですが、これは過剰です。

1

これは質問に答えるのではなく、それが適切である:

self.__dict__[name] = value 

これは、Pythonドキュメント(SETATTR "> HTTPによって推奨され、おそらく

parentClass.__setattr__(self, name, value) 

よりも優れている://ドキュメントこれはparentClassの振る舞いについて何も想定していないので、通常の場合にはもっと意味があります。setattr

4年前の迷惑なアドバイスのためによろしいですか!

関連する問題