2012-01-03 98 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名为元组的一个很好的总结。