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

后端 未结 2 1417
日久生厌
日久生厌 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:55

    Perhaps you are coming from a Java background, but multiple inheritance doesn't do what you'd expect it does in Python. Calling super from the init of the defaultOrderedDict calls the super() as the init of defaultdict and never the init of OrderedDict. The map attribute is first defined in the __init function of OrderedDict. The implementation is the following (from source):

    def __init__(self, *args, **kwds):
        '''Initialize an ordered dictionary.  The signature is the same as
        regular dictionaries, but keyword arguments are not recommended because
        their insertion order is arbitrary.
    
        '''
        if len(args) > 1:
            raise TypeError('expected at most 1 arguments, got %d' % len(args))
        try:
            self.__root
        except AttributeError:
            self.__root = root = []                     # sentinel node
            root[:] = [root, root, None]
            self.__map = {}
        self.__update(*args, **kwds)
    

    Note that this doesn't have to do with the attribute being private. A minimal example with multiple inheritance can illustrate this:

    class Foo:
        def __init__(self):
            self.foo=2
    
    class Bar:
        def __init__(self):
            self.bar=1
    
    class FooBar(Foo,Bar):
         def __init__(self):
            super().__init__()
    
    fb = FooBar()
    
    fb.foo
    >>2 
    fb.bar
    >>AttributeError: 'FooBar' object has no attribute 'bar'
    

    So, the constructor of Bar was never called. Pythons method resolution order goes from left to right until it finds a class with the function name it seeks (in this case init) and then ignores all other classes on the right (in this case Bar)

提交回复
热议问题