Множественное наследование с несколькими базовыми классами - PullRequest
1 голос
/ 25 января 2020

, пожалуйста, помогите мне понять концепцию множественного наследования здесь, в Python ( Я из C# фона, который не поддерживает множественное наследование ).

Я использую Python 3.7.6 .

В приведенном ниже коде класс Apple наследует классы ToyFruit, NaturalFruit, FakeFruit и RoboticFruit. В то время как ToyFruit, NaturalFruit и FakeFruit наследуют Fruit базовый класс, RoboticFruit имеет другой BaseClass Robot.

Я заметил, что RoboticFruit и Robot вообще не вызывают.

class Fruit:
    def __init__(self, name):
        print("This is the Fruit __init__ function")
        self.test = "BaseClass"
        self.name = name
        print("Fruit object created")


class NaturalFruit(Fruit):
    def __init__(self, name):
        print("This is the NaturalFruit __init__ function")
        super().__init__(name)
        self.type = "Natural"
        print("This is a Natural Fruit")
        self.test = "NaturalClass"
        print("Natural Fruit object created")


class FakeFruit(Fruit):
    def __init__(self, name):
        print("This is the FakeFruit __init__ function")
        super().__init__(name)
        self.type = "Fake"
        print("This is a Fake Fruit")
        self.test = "FakeClass"
        print("Fake Fruit object created")


class ToyFruit(Fruit):
    def __init__(self, name):
        print("This is the ToyFruit __init__ function")
        super().__init__(name)
        self.type = "Toy"
        print("This is the Toy Fruit")
        self.test = "ToyClass"
        print("Toy Fruit object created")


class Robot:
    def __init__(self, name):
        print("This is the ROBOT __init__ function")
        self.test = "RobotClass"
        self.name = name
        print("Robot object created")


class RoboticFruit(Robot):
    def __init__(self, name):
        super().__init__("RoboticFruit")
        print("Robotic Fruit")


class Apple(ToyFruit, NaturalFruit, FakeFruit, RoboticFruit):
    def __init__(self):
        super().__init__("Apple")
        print("Apple object created")


apple = Apple()
# print(apple.name)
print(apple.test)

ВЫХОД: -

This is the ToyFruit __init__ function
This is the NaturalFruit __init__ function
This is the FakeFruit __init__ function
This is the Fruit __init__ function
Fruit object created
This is a Fake Fruit
Fake Fruit object created
This is a Natural Fruit
Natural Fruit object created
This is the Toy Fruit
Toy Fruit object created
Apple object created
ToyClass

Если я поменяю заказ на

class Apple(RoboticFruit, ToyFruit, NaturalFruit, FakeFruit):

Затем ToyFruit, NaturalFruit, FakeFruit и Fruit __init__ методы вообще не вызываются. Я не понимаю, почему конструкторы класса RoboticFruit пропускаются.

Ответы [ 2 ]

2 голосов
/ 25 января 2020

В случае множественного наследования super() делегируется следующему объекту в Порядке разрешения методов (MRO). Мы можем видеть MRO класса Apple:

print(Apple.__mro__)

# output:
(
<class '__main__.Apple'>, 
<class '__main__.ToyFruit'>, 
<class '__main__.NaturalFruit'>, 
<class '__main__.FakeFruit'>, 
<class '__main__.Fruit'>, 
<class '__main__.RoboticFruit'>, 
<class '__main__.Robot'>, 
<class 'object'>
)

Так что я предполагаю, что RoboticFruit и Robot не вызываются, потому что в классе Fruit нет вызова, подобного super().__init__(name), который является предыдущим RoboticFruit в этом порядке (MRO). Если вы добавите вызов к super() в Fruit, он должен работать правильно:

class Fruit:
    def __init__(self, name):
        print("This is the Fruit __init__ function")
        super().__init__(name)
        self.test = "BaseClass"
        self.name = name
        print("Fruit object created")
0 голосов
/ 26 января 2020

Я не уверен, что он возвращает желаемый результат, но это может быть возможность заменить super() вызовы на __init__ жестко закодированными вызовами:

class Fruit:
    def __init__(self, name):
        print("This is the Fruit __init__ function")
        self.test = "BaseClass"
        self.name = name
        print("Fruit object created")


class NaturalFruit(Fruit):
    def __init__(self, name):
        print("This is the NaturalFruit __init__ function")
        Fruit.__init__(self, name)
        self.type = "Natural"
        print("This is a Natural Fruit")
        self.test = "NaturalClass"
        print("Natural Fruit object created")


class FakeFruit(Fruit):
    def __init__(self, name):
        print("This is the FakeFruit __init__ function")
        Fruit.__init__(self, name)
        self.type = "Fake"
        print("This is a Fake Fruit")
        self.test = "FakeClass"
        print("Fake Fruit object created")


class ToyFruit(Fruit):
    def __init__(self, name):
        print("This is the ToyFruit __init__ function")
        Fruit.__init__(self, name)
        self.type = "Toy"
        print("This is the Toy Fruit")
        self.test = "ToyClass"
        print("Toy Fruit object created")


class Robot:
    def __init__(self, name):
        print("This is the ROBOT __init__ function")
        self.test = "RobotClass"
        self.name = name
        print("Robot object created")


class RoboticFruit(Robot):
    def __init__(self, name):
        Robot.__init__(self, "RoboticFruit")
        print("Robotic Fruit")


class Apple(ToyFruit, NaturalFruit, FakeFruit, RoboticFruit):
    def __init__(self):
        ToyFruit.__init__(self, "Apple")
        NaturalFruit.__init__(self, "Apple")
        FakeFruit.__init__(self, "Apple")
        RoboticFruit.__init__(self, "Apple")
        print("Apple object created")


apple = Apple()
#print(apple.name)
print(apple.test)

# output:
# This is the ToyFruit __init__ function
# This is the Fruit __init__ function
# Fruit object created
# This is the Toy Fruit
# Toy Fruit object created
# This is the NaturalFruit __init__ function
# This is the Fruit __init__ function
# Fruit object created
# This is a Natural Fruit
# Natural Fruit object created
# This is the FakeFruit __init__ function
# This is the Fruit __init__ function
# Fruit object created
# This is a Fake Fruit
# Fake Fruit object created
# This is the ROBOT __init__ function
# Robot object created
# Robotic Fruit
# Apple object created
# RobotClass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...