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 次 |
最近记录: |