Reputation: 3081
I am trying to understand some basic OOP in python. If I try to subclass a class like list, how do I invoke the parent constructor? After tinkering for a bit I found that it is:
super(subclass_name, self).__init__(args).
However I dont intuitively understand this. Why can't I just do list(args)? or
list.__init__(args)?
The following is the relevant snippet:
class slist(list):
def __init__(self, iterable):
#super(slist, self).__init__(iterable) <--- This works)
list.__init__(iterable) # This does not work
self.__l = list(iterable)
def __str__(self):
return ",".join([str(s) for s in self.__l])
Upvotes: 2
Views: 879
Reputation: 22953
list.__init__(iterable)
is incorrect. You need to tell __init__()
which object it is initializing. list(args)
is even more incorrect, as it creates a completely new list object rather than initializing your object. It calls list.__new__()
rather than list.__init__()
. You need to pass self
to the constructor call to correctly initialize the parent class:
list.__init__(self, args)
and that would work. Using super()
though usually allows for cleaner syntax. For example, the above could be rewritten as:
super(slist, self).__init__(args)
However, the main reason useage of super()
is encouraged over simply calling the parent constructor, is for cases where you have multiple inheritance. super()
will automatically call the constructor of each parent class in the correct order. This is closely related to Python's Method Resolution Order.
Upvotes: 2
Reputation: 280261
list.__init__(iterable)
is missing the information of which list to initialize, and list(iterable)
builds a different list entirely unrelated to the one you're trying to initialize.
If you don't want to use super
, you can do list.__init__(self, iterable)
.
Upvotes: 4