2016-07-25 7 views
0

set文とget文を使用する関数の辞書を作成し、setとして使用して関数を取得する方法はありますか?辞書項目で__get__、__set__を使用しますか?

class thing(object): 
    def __init__(self, thingy) 
     self.thingy = thingy 
    def __get__(self,instance,owner): 
     return thingy 
    def __set__(self,instance,value): 
     thingy += value 

theDict = {"bob":thing(5), "suzy":thing(2)} 

theDict["bob"] = 10 

辞書が数値

print theDict["bob"] 
>>> 10 

のエントリを置き換えることで、結果は10が設定された機能の中に入ることで、既存の5

print theDict["bob"] 
>>> 15 

実際の結果に追加したかったですなぜ、私はちょうど..のような機能を作ることができないのですか? theDict ["bob"]。add(10) は、 g関数を使用してgetとgetを実行します。私が扱っているケースは端的なケースであり、この1つのケースで作業をするためにすべてを再プログラムするのは意味がありません。

このセットのインスタンスを格納するには何らかの手段が必要ですが、アクセス可能であるが既存の参照を破損する可能性のある深さのレイヤを作成しないようにする必要があります。

実際のコードは尋ねないでください。問題をカプセル化するためにコードページが必要になります。

+0

は一体何?いいえ、 '__get__'と' __set__'はそのようなことはしません。私はあなたの既存のデザインが記述子が添付されているクラスのオブジェクトではなく、ディスクリプタ自体に 'thingy'を格納しているならば、あなたの既存のデザインを非常に疑っています。 – user2357112

+0

私はこの質問についてもかなり混乱しています...あなたがしようとしていることに関連する '__get__'と' __set__'の仕組みを理解できません。あなたが望む方法でデリゲートされたdictを更新するために '__getitem__'と' __setitem__'をオーバーライドするラッパークラスを作成することができました。しかし、いくつかの実際のコード(またはあなたが実際に達成しようとしているものの少なくとも最小限の例)を見ることなく、それ以上のアドバイスをするのは難しいでしょう... – mgilson

+0

どのオブジェクトがあなたのカスタムビヘイビアを担当するかを決めます。今すぐ辞書( 'theDict [" bob "] = 10')のアクションを実行して' theDict'のキー 'bob'に10を割り当てます(ご覧の通り、しかし、「もの」のカスタムロジックを悪用しようとします。カスタムロジックが '物事 'にある場合は、'物事'にそれを行うように依頼してください.dictを要求しないでください。そして、できなければ、あなたのデザインを考え直してください。 –

答えて

1

あなたは(も)あなたのThingクラスを認識しており、別々に扱う辞書の特殊なバージョンを使用できる場合は、それを行うことができます:

class Thing(object): 
    def __init__(self, thingy): 
     self._thingy = thingy 
    def _get_thingy(self): 
     return self._thingy 
    def _set_thingy(self, value): 
     self._thingy += value 

    thingy = property(_get_thingy, _set_thingy, None, "I'm a 'thingy' property.") 

class ThingDict(dict): 
    def __getitem__(self, key): 
     if key in self and isinstance(dict.__getitem__(self, key), Thing): 
      return dict.__getitem__(self, key).thingy 
     else: 
      return dict.__getitem__(self, key) 

    def __setitem__(self, key, value): 
     if key in self and isinstance(dict.__getitem__(self, key), Thing): 
      dict.__getitem__(self, key).thingy = value 
     else: 
      dict.__setitem__(self, key, value) 


theDict = ThingDict({"bob": Thing(5), "suzy": Thing(2), "don": 42}) 

print(theDict["bob"]) # --> 5 
theDict["bob"] = 10 
print(theDict["bob"]) # --> 15 

# non-Thing value 
print(theDict["don"]) # --> 42 
theDict["don"] = 10 
print(theDict["don"]) # --> 10 
+0

これはほとんど私のために働くが、1つ例外がある。渡された引数の数。私が辞書に入れているクラスは、渡されたインスタンスを使用しています。このdictメソッドは、そのインスタンスを渡すようには見えません。この方法でそれを行う方法はありますか? –

1

いいえ、theDict["bob"] = 10を実行するため、Pythonランタイムは前の値がすべてtheDict["bob"]であるメソッドを呼び出しません。 myObject.mydescriptor = 10が記述子セッターを呼び出すときとは異なります。

refcountが0に達すると、前の値の__del__が呼び出されることがありますが、そこには行かないでください。

このようなことをしたい場合は、コンテンツではなく辞書の仕組みを変更する必要があります。たとえば、dictをサブクラス化することができます(通常の警告で、悪い、悪い、間違ったLiskovではない派生クラスを書くことができます)。あるいは、ゼロからインスタンスcollections.MutableMappingを実装することもできます。しかし、私はそれに格納されている特別な値を使用してdictの通常の操作をハイジャックする方法はないと思う。

+0

'collections.MutableMapping'の提案に+1してください。参照してください:[http://stackoverflow.com/a/3387975/6084928](http://stackoverflow.com/a/3387975/6084928) –

+0

@Lex:具体的な 'collections.MutableMapping'コンテナを実装することは、 'dict'の比較的簡単なサブクラスはうまくいきます。 [私の答え](http://stackoverflow.com/a/38574478/355230)を参照してください。 – martineau

+0

公正なポイント。あなたの解決策はより簡潔です。 –

0

theDict["bob"] = 10bobtheDict10を割り当てます。 まず、魔法の方法__get____set__について知っておくべきだと思います。移動先:https://docs.python.org/2.7/howto/descriptor.htmlクラスを使用する方がdictより簡単です。

関連する問題