I am confused about the convention of passing *args
in super().__init__()
in python inheritance.
I understand the need to use keyword arguments **kwargs
so the required arguments can be taken by the class in CRO if needed, but why there's also a *args
?
Example: Suppose Sneaky is used as part of a multiple inheritance class structure such as:
class Sneaky:
def __init__(self, sneaky = false, *args, **kwargs):
super().__init__(*args, **kwargs)
self.sneaky = sneaky
class Person:
def __init__(self, human = false, *args, **kwargs):
super().__init__(*args, **kwargs)
self.human = human
class Thief(Sneaky, Person):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
t = Thief(human = true, sneaky = true)
print(t.human)
# True
So what if we have below instead aka remove the *args?
class Sneaky:
def __init__(self, sneaky = false, **kwargs):
super().__init__( **kwargs)
self.sneaky = sneaky
class Person:
def __init__(self, human = false, **kwargs):
super().__init__(**kwargs)
self.human = human
class Thief(Sneaky, Person):
def __init__(self, **kwargs):
super().__init__( **kwargs)
t = Thief(human = true, sneaky = true)
print(t.human)
# True
Passing in *args
means that you can initialize your Thief
like
>> x = Thief(True, False)
>> x.human
False
>> x.sneaky
True
This is confusing to read, and difficult to trace with multiple inheritance, but it could be useful. Maintaining this capability means you could do
sneaky = (True, False, True,)
human = (True, False, False,)
thieves = [Thief(*args) for args in zip(sneaky, human)]
This is a bit contrived, but I think it illustrates why you might want to allow positional arguments.
If you do want to remove the *args
and not support positional arguments, you can exclude them from Sneaky
and Person
as well by adding *,
after self,
.
class Sneaky:
def __init__(self, *, sneaky=False, **kwargs):
super().__init__(**kwargs)
self.sneaky = sneaky
class Person:
def __init__(self, *, human=False, **kwargs):
super().__init__(**kwargs)
self.human = human
This does not put all positional arguments in an un-named *
. This will raise a TypeError
if you try to provide a positional arugment.