2016-07-26 9 views
-2
class Myclass(object): 
    def get_val(self): 
     return 100 

my_obj = MyClass() 
data = { 
    'key_1': my_obj, 
    ... # other fields 
} 

後、私はそれが価値だとオブジェクトを変更する必要があり、私は多分、再帰的に、このように辞書を反復処理することができます:Python:オブジェクトが別のものに変わる可能性はありますか?

for key in data: 
    if type(data[key]) is MyClass: 
     data[key] = data[key].get_val() 

しかしmy_obj自体を経由してこれを実行することが可能ですか?

私はそう思うわけではありません。なぜなら、Pythonではポインタを操作することができないので、Cで行うことができますが、より良い方法はありますか?

+0

オブジェクトはそれ自身を行うことはできませんが、dictionaryのサブクラスは 'data [key]'ルックアップの処理方法をかなり簡単にオーバーライドできます。 –

+0

既に述べたように、クラス内で特定の値を返すためにオーバーライドできる魔法のバリエーションがあります –

+2

なぜこれを最初に行う必要がありますか? –

答えて

0

オブジェクトは、自分自身の参照の一部またはすべてを他のものと置き換えることはできません。期間。しかし、あなたはポインタオブジェクトの辞書(実際のデータを返すために.get()方法のいくつかのフォームを持っている)を持っている必要がありますならば、ちょうどからデータを取得するとき、あなたが適切なロジックを追加できるようになるdictサブクラスの__getitem__メソッドをオーバーライド

辞書:

class MyDict(dict): 
    def __getitem__(self,item): 
     value = dict.__getitem__(self,item) #may raise error 
     if isinstance(value, Myclass): 
      return value.get_val() 
     else: 
      return value 

my_obj = Myclass() 

data = MyDict({ 
    'key_1': my_obj, 
    # other fields 
}) 

assert data["key_1"] == 100 

いますが、この変更のみとなるよう、より完全な実装がcollections.MutableMappingで行うことができる変更__getitem__を使用することはありません.items()または.get()などを使用して、ルックアップのいずれかの方法であって、

import collections 

class MyDict(collections.MutableMapping): 
    __slots__ = ["raw_dict"] 
    def __init__(self,*args,**kw): 
     self.raw_dict = dict(*args,**kw) 

    def __getitem__(self,item): 
     value = self.raw_dict[item] 
     if isinstance(value, Myclass): 
      return value.get_val() 
     return value 

    def __setitem__(self,item, value): 
     self.raw_dict[item] = value 
    def __delitem__(self, item): 
     del self.raw_dict[item] 
    def __len__(self): 
     return len(self.raw_dict) 
    def __iter__(self): 
     return iter(self.raw_dict) 

その後.get.pop.itemsなどのような他のすべてのメソッドは、すべてここに定義されたものから作成されます。元のポインタオブジェクトはまだdata.raw_dict["key_1"]でアクセス可能なので、何も隠されている/失われたトラックはありません。

関連する問題