drs*_*drs 11 python multiple-inheritance ordereddictionary python-3.x defaultdict
我首次尝试将collections模块中两个字典的功能组合在一起,创建一个继承它们的类:
from collections import OrderedDict, defaultdict
class DefaultOrderedDict(defaultdict, OrderedDict):
def __init__(self, default_factory=None, *a, **kw):
super().__init__(default_factory, *a, **kw)
Run Code Online (Sandbox Code Playgroud)
但是,我无法为此词典分配项目:
d = DefaultOrderedDict(lambda: 0)
d['a'] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.3/collections/__init__.py", line 64, in __setitem__
self.__map[key] = link = Link()
AttributeError: 'DefaultOrderedDict' object has no attribute '_OrderedDict__map'
Run Code Online (Sandbox Code Playgroud)
实际上,关于如何创建类似对象的这个问题有通过扩展OrderedDict类并手动重新实现所提供的其他方法来实现它的答案defaultdict.使用多重继承会更清晰.为什么不起作用?
原因是代替在MRO中调用下一个类的init方法defaultdict__init__调用init,PyDict_Type因此__map在OrderedDict__init__中设置的某些属性从未被初始化,因此错误.
>>> DefaultOrderedDict.mro()
[<class '__main__.DefaultOrderedDict'>,
<class 'collections.defaultdict'>,
<class 'collections.OrderedDict'>,
<class 'dict'>, <class 'object'>]
Run Code Online (Sandbox Code Playgroud)
而且defaultdict没有自己的__setitem__方法:
>>> defaultdict.__setitem__
<slot wrapper '__setitem__' of 'dict' objects>
>>> dict.__setitem__
<slot wrapper '__setitem__' of 'dict' objects>
>>> OrderedDict.__setitem__
<unbound method OrderedDict.__setitem__>
Run Code Online (Sandbox Code Playgroud)
所以,当你调用d['a']= 1时,在搜索__setitem__Python时到达OrdereredDict __setitem__并且他们对未初始化__map属性的访问引发了错误:
修复将是__init__两个defaultdict并OrderedDict明确调用:
class DefaultOrderedDict(defaultdict, OrderedDict):
def __init__(self, default_factory=None, *a, **kw):
for cls in DefaultOrderedDict.mro()[1:-2]:
cls.__init__(self, *a, **kw)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2174 次 |
| 最近记录: |