简体   繁体   中英

Difference between assigning values to attributes in child class and parent class

Choice A:

class Mammal(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return str(self.name)

class Human(Mammal):
    def __init__(self, name):
        self.name = name

me = Human("John")
print(me)

Choice B:

class Mammal(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return str(self.name)

class Human(Mammal):
    def __init__(self, name):
        super(Human, self).__init__(name)


me = Human("John")
print(me)

Both choices return the same result, but can someone please explain what's the difference between assigning the name to child class (Human) and the parent class (Mammal)? Is there a better one between these two choices?

Thank you very much!

This is really a question of class design and maintenance. Obviously in this case there are no characteristics that Humans have that Mammals don't and no other Mammals. But, for instance, let's say you later update Mammal to have a "feet" attribute:

class Mammal(object):
    def __init__(self, name, feet):
        self.name = name
        self.feet = feet

Mammals now have a number of feet, and so you might expect Humans to also. But me.feet will throw an error, because the Human __init__ didn't initialize it, and the Mammal __init__ didn't run. Nor can you declare feet with me = Human('Joe', 2) , because the Human __init__ doesn't take that argument. So you've created a maintenance problem -- Humans are now not really good Mammals, because some of their promised attributes are always undefined.

Using super avoids this problem:

class Human(Mammal):
    def __init__(self, name):
        super(Human, self).__init__(name, 2)

Of course, this requires you to subclass Human if you want a lot of pirates, but that's another problem.

The converse situation might be if you decided that most Mammals don't have names. Obviously, in this case, you would want to define name only in the Human __init__ .

In the first example, you only say that Human inherits from Mammal ( the .__init__ on Mammal is not called), and if you try to use self.name you'll get an attribute error.

In the second example you are, in Human class, using the self.name from Mammal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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