16.21. OOP Inheritance Super

  • super() Calls a method from superclass

  • Order/location is important

  • Raymond Hettinger - Super considered super! - PyCon 2015 [1]

16.21.1. Super With Methods

>>> class User:
...     def say_hello(self):
...         print(f'User says hello')

Defining method with the same name will overload one inherited from superclass.

>>> class Admin(User):
...     def say_hello(self):
...         print(f'Admin says hello')
...
>>> mark = Admin()
>>> mark.say_hello()
Admin says hello

Order of super() is important:

>>> class Admin(User):
...     def say_hello(self):
...         super().say_hello()
...         print(f'Admin says hello')
>>>
>>>
>>> mark = Admin()
>>> mark.say_hello()
User says hello
Admin says hello
>>> class Admin(User):
...     def say_hello(self):
...         print(f'Admin says hello')
...         super().say_hello()
>>>
>>>
>>> mark = Admin()
>>> mark.say_hello()
Admin says hello
User says hello

16.21.2. Super With Attributes

>>> class User:
...     def __init__(self):
...         self.firstname = 'Mark'
...         self.lastname = 'Watney'
...         self.is_admin = False

Without super():

>>> class Admin(User):
...     def __init__(self):
...         self.is_admin = True
...
>>>
>>> mark = Admin()
>>> vars(mark)
{'is_admin': True}

With super() first:

>>> class Admin(User):
...     def __init__(self):
...         super().__init__()
...         self.is_admin = True
...
>>> mark = Admin()
>>> vars(mark)
{'firstname': 'Mark', 'lastname': 'Watney', 'is_admin': True}

With super() last (will override child's attributes):

>>> class Admin(User):
...     def __init__(self):
...         self.is_admin = True
...         super().__init__()
...
>>>
>>> mark = Admin()
>>> mark.is_admin
False

16.21.3. Super Init with Args

>>> class User:
...     def __init__(self, firstname, lastname):
...         self.firstname = firstname
...         self.lastname = lastname
...         self.is_admin = False
>>>
>>>
>>> class Admin(User):
...     def __init__(self, firstname, lastname):
...         super().__init__(firstname, lastname)
...         self.is_admin = True
>>>
>>>
>>> mark = Admin('Mark', 'Watney')
>>> vars(mark)
{'firstname': 'Mark', 'lastname': 'Watney', 'is_admin': True}

16.21.4. References

16.21.5. Assignments

Code 16.27. Solution
"""
* Assignment: OOP Overload Super
* Type: class assignment
* Complexity: easy
* Lines of code: 6 lines
* Time: 5 min

English:
    1. Create class `Astronaut` which inherits from `Person`
    2. Class `Astronaut` takes two arguments `name` and `mission`
    3. Set attribute `mission` in `Astronaut` inicializer method
    4. Call initializer method of `Person` passing `name` as an argument
    5. Define method `show()` returning name and after coma - a mission name
    6. Run doctests - all must succeed

Polish:
    1. Stwórz klasę `Astronaut` dziedziczącą po `Person`
    2. Klasa `Astronaut` przyjmuje dwa argumenty `name` i `mission`
    3. Ustaw atrybut `mission` w metodzie inicjalizacyjnej w `Astronaut`
    4. Wywołaj metodę inicjalizacyjną z `Person` podając `name` jako argument
    5. Zdefiniuj metodę `show()` zwracającą imię i po przecinku - nazwę misji
    6. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> mark = Astronaut('Watney', 'Ares 3')
    >>> mark.show()
    'Watney, Ares 3'
    >>> melissa = Astronaut('Lewis', 'Ares 3')
    >>> melissa.show()
    'Lewis, Ares 3'
"""


class Person:
    def __init__(self, name):
        self.name = name