2011-01-23 5 views
5

__setattr__を定義すると、クラスで定義するすべてのsetterメソッド/プロパティがオーバーライドされます。フィールドにプロパティが存在する場合は、プロパティで定義されたセッターメソッドを使用し、それ以外の場合はself.__dict__[name] = valueを使用します。プロパティを持たないフィールドの代入には__setattr__を定義する必要がありますが、プロパティが定義されたフィールドにはsetter/getter関数を使用する必要があります。

ヘルプ!私は__setitem__を使用する1つの解決策を見つけましたが、これは私にとっては役に立ちません

ここで、プロパティはPythonクラスに格納されていますか?どうすればそれらにアクセスできますか?

セッターメソッドが定義されているフィールドのプロパティを使用するように、__setattr__を定義するにはどうすればよいですか?また

class test(object): 

def _get_gx(self): 
    print "get!" 
    return self.__dict__['gx'] 

def _set_gx(self, gx): 
    print "set!" 
    self.__dict__['gx'] = gx 
    gx = property(_get_gx, _set_gx) 

def __setattr__(self, name, value): 
    self.__dict__[name] = value 

def __init__(self): 
    pass 

はなぜ "を取得!" です

x = test() 
x.gx = 4 
x.gx 

prints: 

    "gets!" 
    "gets!" 
    4 
+0

あなたのインデントが壊れた状態でこれを処理するのは難しいでしょう。あなたが尋ねる唯一の一般的な質問は「記述子はどこに住んでいますか」であり、答えはクラスdictにあります。 – aaronasterling

+0

これらはクラス辞書にはありません。私が定義したプロパティは、クラス辞書には表示されません。 – HaltingState

+1

あなたは何か間違っている。記述子はクラス辞書に存在します。詳細については、Pythonデータモデルを見てください。あなたがインデントを修正したら、私はあなたのためにそれを把握します。 – aaronasterling

答えて

10

__setattr__機能を書き換える必要があります。 docsによると、新しいスタイルクラスはself.__dict__[attr] = valueの代わりにbaseclass.__setattr__(self, attr, value)を使用する必要があります。前者は任意の記述子を検索し、後者は直接的に記述子を割り当てます。

だからあなたの方法は

def __setattr__(self, name, value): 
    object.__setattr__(self, name, value) 

または

def __setattr__(self, name, value): 
    super(Test, self).__setattr__(name, value) 

として書き直すと、あなたは大丈夫です。コード

class Test(object): 
    @property 
    def gx(self): 
     print "getting gx" 
     return self.__dict__['gx'] 

    @gx.setter 
    def gx(self, value): 
     print "setting gx" 
     self.__dict__['gx'] = value 

    def __setattr__(self, attr, value): 
     print "using setattr"    
     object.__setattr__(self, attr, value) 

t = Test() 
t.gx = 4 
t.dummy = 5 
print t.gx 
print t.dummy 

print dir(Test) 

出力

using setattr 
setting gx 
getting gx 
using setattr 
4 
5 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'gx'] 

バージョンが二回ゲッターを呼び出している理由を私は知りません。これはしません。また、記述子がどこに住んでいるかについてのあなたの質問に答えるために、それをクラスdictの最後のエントリとして明白に見ることができます。

例では、__setattr__を実行する必要はありません。 Pythonは、foo.__dict__にエントリがあるかどうかに関係なく、常にfoo.bar = xfoo.__dict__['bar'] = xという割り当てを書き込みます。 __setattr__は、値を変換したり、代入などを記録したい場合に使用します。

関連する問題