How to use and what is 'super' in Python classes?

14

How to use and what is the super in% with classes Python ?

    
asked by anonymous 25.06.2014 / 17:16

1 answer

18
The super is for - in an inheritance relationship between a Base class and another Derivada - allow the Derivada class to refer explicitly to the Base class.

Suppose the following classes:

class Base(object):
    def __init__(self):
        print 'Construindo a classe Base'

class Derivada(Base):
    def __init__(self):
        print 'Construindo a classe Derivada'

x = Derivada()

When this code is executed, only "Constructing the Derivative class" will be printed on the screen because the Base constructor was not called at any time. If we want it to be, we have two alternatives:

  • Refer to the constructor of Base directly:

    class Derivada(Base):
        def __init__(self):
            Base.__init__(self)
    
  • Use super , allowing the interpreter to find the correct superclass for you:

    class Derivada(Base):
        def __init__(self):
            super().__init__()               # Python 3
            super(Derivada, self).__init__() # Python 2
    
  • The super is not just for the constructor, of course: any method of class Base can be called this way by class Derivada :

    class Derivada(Base):
        def foo(self, arg): pass
        def bar(self, arg):
            super().foo(arg) # Chama o método foo de Base, não de si própria
    

    Advantages

    At first glance, there does not seem to be much benefit from using method 2 (with super ) compared to method 1 (naming the base class explicitly), except perhaps for the simpler code (in Python 3; , it gets even longer!). But as this post (such as pointed out by user11802 in comments ), there are situations in that the use of super actually makes a lot of difference. Consider for example a subclass of dict that registers in a log file every time an item is changed:

    class LoggingDict(dict):
        def __setitem__(self, key, value):
            logging.info('Setting %r to %r' % (key, value))
            super().__setitem__(key, value)
    

    Suppose we wanted to modify this class to inherit from MeuDict instead of dict . In this case, just make the change in the class definition:

    class LoggingDict(MeuDict):
    

    and everything else would remain the same. If access to the base methods were explicit, we would have to modify every part that refers to dict to switch to MeuDict . In other words, the use of super decouple the base class and the derivative to some extent, improving code maintainability.

    The linked article has other examples for more complex situations, some involving multiple inheritance (situation where the utility of super becomes more evident).

    25.06.2014 / 18:12