Reputation: 748
Is it good practice to initialize a parent class from within the subclass, so that the parent class attributes are available to the created subclass instance? Are there alternatives or best practices in doing so?
As an example:
class Animal(object):
def __init__(self, name, weight, cute=False, image=None):
#Instantiation attributes
self.name = name
self.weight = weight
self.cute = cute
self.image = image
#Attributes common to all animals
self.extinct = False
def get_animal_stats(self):
print arbitrary_animal_stat
class Dog(Animal):
def __init__(self, name, weight):
Animal.__init__(self, name, weight, cute=True, image="dog.com")
#Additional attributes unique to dogs
self.number_legs = 4
self.teeth = True
def make_noise(self):
print "Bark!"
As I understand it, without initializing the parent class during the subclass initialization, the subclass object only has access to its own attributes (ie. number_legs and teeth, and make_noise) and not the parent classes attributes or methods (ie. extinct, and get_animal_stats).
I find myself writing many small classes for predefined objects but have to initialize the parent with the child. In this way, I can create a simple Animal on the fly or create a more descriptive Animal through the Dog subclass.
What is the proper way to access Parent attributes and methods from the subclass instance? Am I misunderstanding the use of subclasses?
Upvotes: 2
Views: 1382
Reputation: 24788
Not only is it acceptable, you should almost always call the parent class's constructor. The only reason you would not do so is if you
With new style classes (those that inherit from object), it is better to use super()
as it takes care of resolution order in cases of multiple inheritance. In Python 2.7, use:
class ParentFooA(GrandparentFoo):
def __init__(self):
some_important_initialization_code()
class ChildFoo(ParentFoo):
def __init__(self):
super(ChildFoo, self).__init__()
Note that another nice property is that you don't have to use the name ParentFoo
anywhere in ChildFoo
except when you define inheritance (for instance, in the line class ChildFoo(...)
). It also works for other methods:
class ChildFoo(ParentFoo):
...
def do_buzz(self):
super(ChildFoo, self).do_buzz()
super()
does not work for old-style classes (that is, classes that don't inherit from object
).
This means that with much of the standard library, you still have to call the parent class's constructor explicitly. So in this case:
class OldStyleParent:
def __init__(self):
...
You would have to call OldStyleParent.__init__()
explicitly in __init__()
.
In Python 3, super
's syntax is simply:
class ChildFooInPython3(ParentFoo):
def __init__(self):
super().__init__()
Upvotes: 2
Reputation: 970
class Dog(Animal):
def __init__(self, name, weight):
super(Dog, self).__init__(name, weight, cute=True, image="dog.com")
#Additional attributes unique to dogs
self.number_legs = 4
self.teeth = True
def make_noise(self):
print "Bark!"
Upvotes: -1
Reputation: 89
Nothing wrong with that, although you might want to use super():
super(Dog, self).__init__...
Or in Python 3:
super().__init__...
Upvotes: 1