2012-01-03 99 views
3

我想打一個字典INT,您可以訪問這樣的:覆蓋{}在python

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

所以我做了這個一個:

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

這工作得很好,但如果你嵌套類型的字典它不工作,如:

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

我可以訪問my_dict.property但在邏輯上我不能這樣做,因爲my_dict.property.sub道具erty是默認字典,所以我想要做的是覆蓋默認字典,所以你可以使用{}。

這可能嗎?

回答

7

一個解決方法的問題是在__getattr__方法返回之前包裝使用DictAsMember默認字典:

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}] 喲可以修改解決方法,以便考慮數組,這就是爲什麼我正在尋找一種方法來覆蓋默認詞典 – 2012-01-03 09:46:42

+0

@Félix事情會變得更復雜一些,但列表中的字典仍然可以被包裝。我更新了我的答案,以顯示使用列表中的字典的示例。 – jcollado 2012-01-03 10:06:23

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名爲元組的一個很好的總結。