English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Внутренняя функция super() используется для вызова метода класса-предка (родительского класса).
super() используется для решения проблем множественного наследования, напрямую вызывать методы базового класса по имени класса в случае единственного наследования работает нормально, но при множественном наследовании это涉及到 поисковый порядок (MRO), повторное вызывание (дiamante inheritance) и другие проблемы.
MRO - это таблица порядка разрешения методов класса, которая其实就是 таблица порядка разрешения методов базового класса.
В Python у super() есть два основных использования:
Это позволяет нам избегать явного использования имени базового класса
Обработка множественного наследования
В случае единственного наследования это позволяет нам ссылаться на базовый класс super().
class Mammal(object): def __init__(self, mammalName): print(mammalName, 'является теплокровным животным.') class Dog(Mammal): def __init__(self): print('Собака имеет четыре ноги.') super().__init__('собака') d1 = Dog()
Результат вывода
Собака имеет четыре ноги. Собака - это теплокровное животное
Здесь мы используем код для вызова метода __init__() класса Mammal (из класса Dog)
super().__init__('Dog')
вместо
Mammal.__init__(self, 'Dog')
Поскольку при вызове членов не нужно указывать имя базового класса, это легко изменить имя базового класса (если это необходимо).
# Изменить базовый класс на CanidaeFamily class Dog(CanidaeFamily): def __init__(self): print('Собака имеет четыре ноги.') # Необходимо изменить это super().__init__('собака')super() встроен в返回 агентский объект, вместо объекта, который можно вызвать через доверительную связь методы базового класса. Это называется индиректно (способность super() ссылаться на базовый объект)
Поскольку индиректно это рассчитывается в-runtime, мы можем использовать различные базовые классы в различные моменты времени (если это необходимо).
class Animal: def __init__(self, Animal): print(Animal, 'является животным'); class Mammal(Animal): def __init__(self, mammalName): print(mammalName, 'является теплокровным животным.') super().__init__(mammalName) class NonWingedMammal(Mammal): def __init__(self, NonWingedMammal): print(NonWingedMammal, 'не умеет летать.') super().__init__(NonWingedMammal) class NonMarineMammal(Mammal): def __init__(self, NonMarineMammal): print(NonMarineMammal, 'не умеет плавать.') super().__init__(NonMarineMammal) class Dog(NonMarineMammal, NonWingedMammal): def __init__(self): print('Собака имеет 4 ноги.'); super().__init__('собака') d = Dog() print('') bat = NonMarineMammal('летучая мышь')
Результат вывода
Собака имеет 4 ноги Собака не умеет плавать Собака не умеет летать Собака - это теплокровное животное Собака - это животное Летучая мышь не умеет плавать Летучая мышь - это теплокровное животное Летучая мышь - это животное
Метод解析顺序 (MRO) - это порядок наследования методов при наличии множественного наследования. Вы можете проверить MRO с помощью атрибута __mro__.
>>> Dog.__mro__ (<class 'Dog'>, <class 'NonMarineMammal'>, <class 'NonWingedMammal'>, <class 'Mammal'>, <class 'Animal'>, <class 'object'>)
Так работает MRO:
Методы в вызове наследования всегда вызываются до методов базового класса.
В нашем примере класс Dog вызывается перед NonMarineMammal или NoneWingedMammal. Эти классы вызываются перед Mammal, а Mammal перед Animal, а Animal перед объектом (object).
Если у класса несколько родительских классов, например Dog (NonMarineMammal, NonWingedMammal), то сначала вызывается метод NonMarineMammal, так как он第一位.