简体   繁体   English

多重继承 Python,super().__init__ 问题

[英]Multiple inheritance Python, super().__init__ issue

I'm pretty new to Python and I'm trying to understand multiple inheritance.我对 Python 很陌生,我正在尝试理解多重继承。 Below I have a code, where I need to create an array of Animals .下面我有一个代码,我需要在其中创建一个Animals数组。

  • An Animal can be Domesticated and Feline动物可以驯化猫科动物
  • A Tiger is a Feline Animal老虎猫科动物
  • A Cat is a Domesticated & Feline Animal家养的猫科动物

Here are the classes:以下是课程:

class Animal:
    def __init__(self, birthDate, type, name, numOfLegs):
        self.birthDate = birthDate
        self.type = type
        self.name = name
        self.numOfLegs = numOfLegs


class Domesticated(Animal):
    def __init__(self, birthDate, type, name, numOfLegs, lastVetCheck):
        super().__init__(birthDate, type, name, numOfLegs)
        self.lastVetCheck = lastVetCheck


class Feline(Animal):
    def __init__(self, birthDate, type, name, numOfLegs, mustacheLength):
        super().__init__(birthDate, type, name, numOfLegs)
        self.mustacheLength = mustacheLength


class Cat(Feline, Domesticated):
    def __init__(self, mustacheLength, numOfLegs, name, type, bDate, vetDate):
        Feline.__init__(self, bDate, type, name, numOfLegs, mustacheLength)
        Domesticated.__init__(self,bDate, type, name, numOfLegs, vetDate)


class Tiger(Feline):
    def __init__(self, birthDate, type, name, numOfLegs, mustacheLength):
        super().__init__(birthDate, type, name, numOfLegs, mustacheLength)

Rese of the code:代码的Rese:

animal_array = []
my_cat = Cat('4', '4', 'Tom', 'Mammal', '1.2.3', '3.4.5')
my_animal = Animal('6.7.8', 'Reptile', 'Rafael', '4')
my_tiger = Tiger('1.1.1', 'Mammal', 'Tiger', '4', '9')
animal_array.append(my_cat)
animal_array.append(my_animal)
animal_array.append(my_tiger)

I receive this error:我收到此错误:

Traceback (most recent call last):

  File "C:/Users/Name/PycharmProjects/Pandas/test.py", line 33, in <module>
    my_cat = Cat('4', '4', 'abc', 'mammal', '1.2.3', '3.4.5')

  File "C:/Users/Name/PycharmProjects/Pandas/test.py", line 23, in __init__
    Feline.__init__(self, bDate, type, name, numOfLegs, mustacheLength)

  File "C:/Users/Name/PycharmProjects/Pandas/test.py", line 17, in __init__
    super().__init__(birthDate, type, name, numOfLegs)

TypeError: __init__() missing 1 required positional argument: 'lastVetCheck'

Now I'm sure that it's a simple issue, probably my classes structuring is bad, though I have no clue what to fix.现在我确定这是一个简单的问题,可能是我的类结构不好,尽管我不知道要解决什么问题。 I sure can use any structuring tips since I'm pretty new to OO.我当然可以使用任何结构化技巧,因为我对 OO 还很陌生。

If you design your classes and use super properly, this is a non-issue.如果你设计你的类并正确使用super ,这不是问题。 Every class (even Animal ) should accept arbitrary keyword arguments to pass on to super().__init__ .每个类(甚至Animal )都应该接受任意关键字参数以传递给super().__init__ Each class lists the parameter names it will handle without passing upstream explicitly.每个类都列出了它将处理的参数名称,而无需显式地传递给上游。 When you instantiate an object, only use keyword arguments, which you can enforce in Python 3 by making the named parameters keyword-only.当你实例化一个对象时,使用关键字参数,你可以在 Python 3 中通过将命名参数设置为关键字来强制执行。

If you define each __init__ correctly, then kwargs should be empty by the time object.__init__ is invoked by one of the calls to super .如果你定义每个__init__正常,则kwargs应当由时间空object.__init__被调用的一个调用super

class Animal:
    def __init__(self, *, birthDate, type, name, numOfLegs, **kwargs):
        super().__init__(**kwargs)
        self.birthDate = birthDate
        self.type = type
        self.name = name
        self.numOfLegs = numOfLegs


class Domesticated(Animal):
    def __init__(self, *, lastVetCheck, **kwargs):
        super().__init__(**kwargs)
        self.lastVetCheck = lastVetCheck


class Feline(Animal):
    def __init__(self, *, mustacheLength, **kwargs):
        super().__init__(**kwargs)
        self.mustacheLength = mustacheLength


class Cat(Feline, Domesticated):
    pass


class Tiger(Feline):
    pass



animals = [
    Cat(mustacheLength='4', numOfLegs='4', name='Tom', type='Mammal', bDate='1.2.3', vetDate'3.4.5')
    Animal(birthDate='6.7.8', type='Reptile', name='Rafael', numOfLegs'4')
    Tiger(bDate='1.1.1', type='Mammal', name='Tiger', numLegs='4', mustacheLength='9')
]

Note the lack of repetition;注意没有重复; nothing common to all animals is repeated in any of the subclasses.所有动物的共同点在任何子类中都没有重复。 The only boilerplate is the identical call to super().__init__(**kwargs) in each class's __init__ method.唯一的样板是在每个类的__init__方法中对super().__init__(**kwargs)的相同调用。

Unfortunetly, you can't use super() like that when you're using multiple inheritance and try to send different arguments to each father class.不幸的是,当您使用多重继承并尝试向每个父类发送不同的参数时,您不能像这样使用 super() 。

If you want to leave the structure of the classes as they are, you need to change the code as follows:如果要保持类的结构不变,则需要按如下方式更改代码:

class Animal:
    def __init__(self, birthDate, type, name, numOfLegs):
        self.birthDate = birthDate
        self.type = type
        self.name = name
        self.numOfLegs = numOfLegs


class Domesticated(Animal):
    def __init__(self, birthDate, type, name, numOfLegs, lastVetCheck):
        Animal.__init__(self, birthDate, type, name, numOfLegs)
        self.lastVetCheck = lastVetCheck


class Feline(Animal):
    def __init__(self, birthDate, type, name, numOfLegs, mustacheLength):
        Animal.__init__(self, birthDate, type, name, numOfLegs)
        self.mustacheLength = mustacheLength


class Cat(Feline, Domesticated):
    def __init__(self, mustacheLength, numOfLegs, name, type, bDate, vetDate):
        Feline.__init__(self, bDate, type, name, numOfLegs, mustacheLength)
        Domesticated.__init__(self,bDate, type, name, numOfLegs, vetDate)


class Tiger(Feline):
    def __init__(self, birthDate, type, name, numOfLegs, mustacheLength):
        super().__init__(birthDate, type, name, numOfLegs, mustacheLength)

Example:例子:

my_cat = Cat('4', '4', 'Tom', 'Mammal', '1.2.3', '3.4.5')
print(my_cat.name)

Output:输出:

Tom

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM