• + 7 comments

    Are you familiar with inheritance? I think the easiest way to understand what's going on is to look at the source of Counter and Python's section on inheritance

    Counter is defined as

    class Counter(dict):
    

    So Counter is inheriting the methods from its base class, python's built-in class dict. This gives Counter access to call those methods as if they were its own, it also gives this Counter privilege to override dict's methods with its own. Counter, by default, doesn't alter the way dict keeps its data.

    OrderedDict is what does the dirty work here. It also extends the python's dict, and it does override dict's methods to create a dict that retains the order of items that are added to it.

    So you now have two classes that extend dict: Counter and OrderedDict, and you want Counter to utilize OrderedDict's methods. You do this using multiple inheritance.

    He's created a new class called OrderedCounter that inherits methods from two classes: Counter and OrderedDict. So now all methods from those two classes are available in OrderedCounter. In the case that both classes have the same method, the first class' method takes precedent.

    When you create a new OrderedCounter, it's executing the constructor from Counter, and any time it would use a method inherited from dict, if OrderedCounter overrode that method, that method will be used instead.

    Then "pass" just declares that there are no methods or variables in your new class, it's just a stub created so Counter could access the new methods on OrderedDict.

    # Here's a fun example of what's going on
    
    class Tractor():
        def plow(self):
            print("Plowing regular fields on earth!")
    
    class Farm(Tractor):
        def clean_barn(self):
            print("Mucking the stalls.")
            
        def do_farm_things(self):
            self.plow()
            self.clean_barn()
    
    # Sweet, we have our Farm, and it has a basic tractor
    # But I'm moving to the Moon to start a MoonFarm, which is the same as running a regular Farm, but we need to use a MoonTractor that's modified for plowing moondirt.
    
    class MoonTractor(Tractor):
        def plow(self):
            print("Plowing fields on the moon!")
    
    # Now we just need our stub MoonFarm to extend Farm and MoonTractor
    
    class MoonFarm(Farm, MoonTractor):
        pass
    
    # moon farm
    farm = MoonFarm()
    farm.do_farm_things()
    
    # regular farm
    farm = Farm()
    farm.do_farm_things()