Reputation: 665
I've read the python documentation, but I still have questions about inheritance.
Is this how inheritance is supposed to be handled?
class SuperClass(object):
def __init__(self, super_argument):
super(object, self).__init__()
self.super_argument = super_argument
self.foo()
class ChildClass(SuperClass):
def __init__(self, super_argument):
self.super_argument = super_argument
super(SuperClass, self).__init__()
If so, does that make this an unworkable design for a class which might be inherited?
class SuperClass(object):
def __init__(self, super_argument):
super(object, self).__init__()
self.foo(super_argument) # Argument passed instead without saving in self
Upvotes: 2
Views: 95
Reputation: 121987
It seems in older versions of python you could pass arguments to super, but no longer. What if SuperClass does some sort of setup using its arguments?
I think you've misunderstood which set of arguments you can leave out in 3.x. In Python 2.x, you needed to pass arguments to super
to get the correctly-bound method:
class MyClass(...):
def __init__(self, ...):
super(MyClass, self).__init__(...)
# ^ these arguments ^ not these
In 3.x, you aren't required to supply those arguments, you can just call super().method(...)
, but it will accept them just fine.
This is the same as the behaviour with inheriting object
- you must do it to get a new-style class in 2.x, but 3.x will create a new-style class whether or not you explicitly inherit object
.
Either way, you can pass arguments to the method on super
. So if you're writing only for 3.x, you could do something like:
class MyClass(SuperClass):
def __init__(self, super_arg, my_arg):
super().__init__(super_arg)
# ^ don't need these
# ^ still need these
self.my_arg = my_arg
If inheriting from object, should I call super?
Yes, because you may be involved in multiple inheritance. Compare:
>>> class SuperClass1(object):
def __init__(self):
print("SuperClass1.__init__")
>>> class SuperClass2(object):
def __init__(self):
print("SuperClass2.__init__")
>>> class MyClass(SuperClass1, SuperClass2):
def __init__(self):
print("MyClass.__init__")
super(MyClass, self).__init__()
>>> MyClass()
MyClass.__init__
SuperClass1.__init__
<__main__.MyClass object at 0x02D0CC50>
with:
>>> class SuperClass1(object):
def __init__(self):
print("SuperClass1.__init__")
super(SuperClass1, self).__init__()
>>> class SuperClass2(object):
def __init__(self):
print("SuperClass2.__init__")
super(SuperClass2, self).__init__()
>>> class MyClass(SuperClass1, SuperClass2):
def __init__(self):
print("MyClass.__init__")
super(MyClass, self).__init__()
>>> MyClass()
MyClass.__init__
SuperClass1.__init__
SuperClass2.__init__
<__main__.MyClass object at 0x02BCDC10>
In the former, because SuperClass1
doesn't call super
, SuperClass2.__init__
never gets reached.
Is this handled differently in python 2.7 vs. 3.x?
Hopefully this is now clear - you need to be more explicit in 2.x (or if you're writing code that should work in both versions) but otherwise the functionality is identical, and you should call super
at all levels in both.
Upvotes: 4