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.
super(here).method()orsuper().method(here)?super(SuperClass, self).__init__(super_argument)orsuper(SuperClass, self, super_argument).__init__()SuperClass, selfif you're writing only for 3.x, butsuper_argumentis still used as before.