2016-06-26 144 views
1

我正在使用一個返回嵌套字典的包。 當我的類方法以字典語法訪問此返回對象時,當其他所有內容都處於對象語法中時,感覺很尷尬。 搜索帶來了一堆/ neobunch包,這似乎實現了我後。我還看到了命名建議,但這些並不輕易支持嵌套屬性,大多數解決方案都依賴於在名稱中使用字典進行嵌套。嵌套字典的對象狀屬性訪問

什麼會是更自然的方式來實現這一目標?

data = {'a': 'aval', 'b': {'b1':{'b2a':{'b3a':'b3aval','b3b':'b3bval'},'b2b':'b2bval'}} } 

print(data['b']['b1']['b2a']['b3b']) # dictionary access 
# print(data.b.b1.b2a.b3b) # desired access 

import neobunch 
data1 = neobunch.bunchify(data) 
print(data1.b.b1.b2a.b3b) 

回答

2

下面的類將讓你做你想要的:

class AttrDict(dict): 
    """ Dictionary subclass whose entries can be accessed by attributes 
     (as well as normally). 
    """ 
    def __init__(self, *args, **kwargs): 
     super(AttrDict, self).__init__(*args, **kwargs) 
     self.__dict__ = self 

    @staticmethod 
    def from_nested_dict(data): 
     """ Construct nested AttrDicts from nested dictionaries. """ 
     if not isinstance(data, dict): 
      return data 
     else: 
      return AttrDict({key: AttrDict.from_nested_dict(data[key]) 
           for key in data}) 

data = { 
    "a": "aval", 
    "b": { 
     "b1": { 
      "b2b": "b2bval", 
      "b2a": { 
       "b3a": "b3aval", 
       "b3b": "b3bval" 
      } 
     } 
    } 
} 

data1 = AttrDict.from_nested_dict(data) 
print(data1.b.b1.b2a.b3b) # -> b3bval 
+0

請您詳細說明爲什麼/代碼如何工作?謝謝! –

+0

@BartKleijngeld:你不瞭解哪些部分? – martineau

+0

我不明白字典鍵如何成爲'data1'對象的屬性。我覺得我錯過了一些非常簡單的東西,但如果你能向我解釋那部分內容,我將不勝感激:)。 –

0

一個簡單的類,構建了基本對象可用於:

class afoo1(object): 
    def __init__(self, kwargs): 
     for name in kwargs: 
      val = kwargs[name] 
      if isinstance(val, dict): 
       val = afoo1(val) 
      setattr(self,name,val) 

我借用了argparse.Namespace定義,調整以允許嵌套。

In [172]: dd={'a':'aval','b':{'b1':'bval'}} 

In [173]: f=afoo1(dd) 

In [174]: f 
Out[174]: <__main__.afoo1 at 0xb3808ccc> 

In [175]: f.a 
Out[175]: 'aval' 

In [176]: f.b 
Out[176]: <__main__.afoo1 at 0xb380802c> 

In [177]: f.b.b1 
Out[177]: 'bval' 

它也已經與**kwargs定義(連同*args)它會被使用。 A __repr__的定義也可能很好。

與其他簡單對象一樣,可以添加屬性,例如, f.c = f(遞歸定義)。 vars(f)返回一個字典,儘管它沒有做任何遞歸轉換)。

+0

從功能的角度來看,你的課沒有什麼問題,但它可以有更好的風格。我不會使用'kwargs'作爲常規字典參數,因爲參數名通常用於關鍵字參數,在此上下文中根本不適用。我還會在Python 2中使用'for name,value in kwargs.items()'(或'.iteritems()'),而不是迭代鍵並在下一行查找值。 – Blckknght

+0

是的,雖然錯誤是由來自'命名空間'原始的不完整編輯造成的。 – hpaulj