Why can't I create a default, ordered dict by inheriting OrderedDict and defaultdict?

后端 未结 2 1377
日久生厌
日久生厌 2021-02-19 19:05

My first attempt to combine the features of two dictionaries in the collections module was to create a class that inherits them:

from collections im         


        
2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-19 19:52

    The reason is that the init method of defaultdict instead of calling __init__ of the next class in MRO calls init of PyDict_Type hence some of the attributes like __map that are set in OrderedDict's __init__ are never initialized, hence the error.

    >>> DefaultOrderedDict.mro()
    [,
     ,
     ,
     , ]
    

    And defaultdict don't have their own __setitem__ method:

    >>> defaultdict.__setitem__
    
    >>> dict.__setitem__
    
    >>> OrderedDict.__setitem__
    
    

    So, when you called d['a'] = 1, in search of __setitem__ Python reached OrdereredDict's __setitem__ and their the access of uninitialized __map attribute raised the error:


    A fix will be to call __init__ on both defaultdict and OrderedDict explicitly:

    class DefaultOrderedDict(defaultdict, OrderedDict):
        def __init__(self, default_factory=None, *a, **kw):
            for cls in DefaultOrderedDict.mro()[1:-2]:
                cls.__init__(self, *a, **kw)
    

提交回复
热议问题