2012-01-03 21 views
3

に私はあなたがそのようにアクセスできる辞書int型を作りたい:上書き{}のpython

>>> my_dict["property'] = 3 
>>> my_dict.property 
3 

だから私はこの1つ作った:

class DictAsMember(dict): 
    def __getattr__(self, name): 
     return self[name] 

これはうまく動作しますが、場合をあなたはそれが動作しませんdicts、例えば入れ子にしている:

my_dict = DictAsMember() 
my_dict["property"] = {'sub': 1} 

私はmy_dict.propertyにアクセスできますが、論理的に、私は小道具のでmy_dict.property.subを行うことはできませんertyはデフォルトのdictなので、デフォルトのdictを上書きしたいので、{}を使うことができます。

これは可能ですか?

問題の回避策は __getattr__方法でそれらを返す前に DictAsMemberを使用して、デフォルトの辞書をラップしている

答えて

7

ワン:あなたは可能性があり(これは、オブジェクトの表記法と呼ばれている)

class DictAsMember(dict): 
    def __getattr__(self, name): 
     value = self[name] 
     if isinstance(value, dict): 
      value = DictAsMember(value) 
     elif isinstance(value, list): 
      value = [DictAsMember(element) 
        if isinstance(element, dict) 
        else element 
        for element in value] 

     return value 

my_dict = DictAsMember() 
my_dict["property"] = {'sub': 1} 
print my_dict.property.sub # 1 will be printed 

my_dict = DictAsMember() 
my_dict["property"] = [{'name': 1}, {'name': 2}] 
print my_dict.property[1].name # 2 will be printed 
+0

唯一の問題は、辞書を持つ配列がある場合です。 my_dict ["properties"] = [{'name':1}、{'name':2}] 回避策を変更して配列を考慮に入れてください。なぜデフォルトディクテーションを上書きする方法を探していたのですか? –

+0

@Félix物事は少し複雑になりますが、リスト内の辞書は引き続きラップできます。私はリスト内の辞書を使って例を示すために答えを更新しました。 – jcollado

2

よりもむしろmy_dict.property表記を実装する独自のクラスを書きます代わりに名前付きタプルを使用します。名前付きタプルは、変数の参照や標準タプル構文のようなオブジェクトを使って参照できます。 documentation

[名前のタプル]から属性を参照することにより アクセスできるだけでなく、刃先交換式と反復可能であることのフィールドを持つタプルのようなオブジェクトを作成するために使用されます。その使用例として

from collections import * 

my_structure = namedtuple('my_structure', ['name', 'property']) 
my_property = namedtuple('my_property', ['sub']) 

s = my_structure('fred', my_property(1)) 

s # my_structure(name='fred', property=my_property(sub=1)) will be printed 

s.name # 'fred' will be printed 

s.property # my_property(sub=1) will be printed 

s.property.sub # 1 will be printed 

も名前のタプルの素敵な要約のためのthis questionに受け入れ答えを参照してください。

関連する問題