如何为python "dict-style"类创建一个通用的AttrDict Mixin?



基本上,我希望能够采取dict一样嘎嘎class(例如下面我的示例DICT),并添加一个MixIn,允许我访问DICT的值作为属性…如

print purchase.price # instead of purchase["price"]

背景:我有各种不同的数据库表(不仅仅是DICT的例子),看起来(&呱呱)像一个dict(例如。bsddb),我想定义(然后使用)一个标准的AttrDictMixIn。(因此避免使用样板剪切/粘贴代码)

# First try using a std dict
class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        self.__dict__ = self
        super(AttrDict, self).__init__(*args, **kwargs)
test1=AttrDict()
test1.x="111"
print 1,test1
# Next derive a crude UPPER dict
class DICT(dict): # EXAMPLE ONLY
  def __getitem__(self,key):
    return super(DICT,self).__getitem__(key.upper())
  def __setitem__(self,key,value):
    return super(DICT,self).__setitem__(key.upper(),value)
test2=DICT()
test2["x"]="222"
print 2,test2
# Next define a AttrDict MixIn
class AttrDictMixIn(object):  # This is what I want to work...
    def __init__(self, *args, **kwargs):
        self.__dict__ = self
        return super(AttrDict, self).__init__(*args, **kwargs)
# Apply the MixIn to DICT 
class AttrDICT(DICT,AttrDictMixIn): pass
test3=AttrDICT()
test3.x="333.xxx"
test3["y"]="333.yyy"
print 3,test3,"X is missing"
print 4,"test3.x:",test3.x,"OK"
print 5,"test3['y']:",test3["y"],"OK"
print 6,"test3.y:",test3.y,"DUD"
print 7,"test3['x']:",test3["x"],"DUD"
输出:

1 {'x': '111'}
2 {'X': '222'}
3 {'Y': '333.yyy'} X is missing
4 test3.x: 333.xxx OK
5 test3['y']: 333.yyy OK
6 test3.y:
Traceback (most recent call last):
  File "x.py", line 39, in <module>
    print 6,"test3.y:",test3.y,"DUD"
AttributeError: 'AttrDICT' object has no attribute 'y'

我怀疑我在做一些微不足道的错误…提示的欢迎。(以及指向类似python mixin的参考示例的指针也可能有所帮助)

编辑:如果能解释一下为什么self.__dict__ = self行打破了多重继承,那就更好了。

实现如下:

class AttrDictMixin(object):
    def __getattr__(self, name):
        return self[name]
    def __setattr__(self, name, value):
        self[name] = value
    def __delattr__(self, name):
        del self[name]

设置或删除属性时,相应调用- __getattr____setattr____delattr__

请记住,mixins应该出现在继承的基类之前:

class AttrDict(AttrDictMixin, DICT): pass

最新更新