Функція super() повертає проксі-об’єкт (тимчасовий об’єкт суперкласу), який дозволяє отримати доступ до методів базового класу. Наприклад:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
class Animal(object): def __init__(self, animal_type): print('Animal Type:', animal_type) class Mammal(Animal): def __init__(self): # Викликаємо суперклас super().__init__('Mammal') print('Mammals give birth directly') dog = Mammal() |
Результат:
Animal Type: Mammal
Mammals give birth directly
Синтаксис функції super()
|
1 |
super() |
Параметри функції super()
Функція super() не приймає жодних параметрів.
Використання функції super()
В Python функція super() має два основні варіанти використання:
дозволяє уникнути явного використання імені базового класу;
робота з множинним успадкуванням.
Приклад №1: Функція super() з одинарним успадкуванням
У разі одинарного успадкування ми використовуємо функцію super() для посилання на базовий клас:
|
1 2 3 4 5 6 7 8 9 10 |
class Mammal(object): def __init__(self, mammalName): print(mammalName, 'is a warm-blooded animal.') class Dog(Mammal): def __init__(self): print('Dog has four legs.') super().__init__('Dog') d1 = Dog() |
Результат:
Dog has four legs.
Dog is a warm-blooded animal.
Тут ми викликали метод __init__() класу Mammal (з класу Dog) за допомогою наступного рядка коду:
|
1 |
super().__init__('Dog') |
замість
|
1 |
Mammal.__init__(self, 'Dog') |
Оскільки нам не потрібно вказувати ім’я базового класу, коли ми викликаємо його члени, ми можемо легко змінити ім’я базового класу (за потреби).
|
1 2 3 4 5 6 7 |
# Змінюємо базовий клас на CanidaeFamily class Dog(CanidaeFamily): def __init__(self): print('Dog has four legs.') # Не потрібно змінювати це super().__init__('Dog') |
Вбудована функція super() повертає проксі-об’єкт, який заміщує об’єкт, який може викликати методи базового класу за допомогою делегування. Це називається перенаправленням (можливість посилатися на базовий об’єкт за допомогою функції super()).
Оскільки перенаправлення виявляється під час виконання, ми можемо використовувати різні базові класи у різний час (за потреби).
Приклад №2: Функція super() з множинним успадкуванням
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
class Animal: def __init__(self, Animal): print(Animal, 'is an animal.'); class Mammal(Animal): def __init__(self, mammalName): print(mammalName, 'is a warm-blooded animal.') super().__init__(mammalName) class NonWingedMammal(Mammal): def __init__(self, NonWingedMammal): print(NonWingedMammal, "can't fly.") super().__init__(NonWingedMammal) class NonMarineMammal(Mammal): def __init__(self, NonMarineMammal): print(NonMarineMammal, "can't swim.") super().__init__(NonMarineMammal) class Dog(NonMarineMammal, NonWingedMammal): def __init__(self): print('Dog has 4 legs.'); super().__init__('Dog') d = Dog() print('') bat = NonMarineMammal('Bat') |
Результат:
Dog has 4 legs.
Dog can't swim.
Dog can't fly.
Dog is a warm-blooded animal.
Dog is an animal.
Bat can't swim.
Bat is a warm-blooded animal.
Bat is an animal.
Порядок виклику методів (MRO)
Порядок виклику методів (скор. “MRO” від англ. “Method Resolution Order“) — це порядок, у якому методи повинні успадковуватися за наявності множинного успадкування. Ми можемо переглянути MRO за допомогою атрибуту __mro__. Наприклад:
|
1 2 3 4 5 6 7 |
>>> Dog.__mro__ (<class 'Dog'>, <class 'NonMarineMammal'>, <class 'NonWingedMammal'>, <class 'Mammal'>, <class 'Animal'>, <class 'object'>) |
Ось як працює MRO:
метод похідного класу завжди викликається раніше методу базового класу. У нашому прикладі клас Dog викликається перед NonMarineMammal або NoneWingedMammal. Ці два класи викликаються перед Mammal, який викликається перед Animal, а клас Animal викликається перед object;
якщо батьків декілька, наприклад, Dog(NonMarineMammal, NonWingedMammal), то методи NonMarineMammal викликаються першими, тому що цей клас з’являється першим.
