This question, is a followup to this one.
When using super()
for multiple inheritance, the suggested approach was to use keyword arguments to pass remaining values up the call chain.
When using the ABC
module, is it good practice do the same in the super().__init__
method?
The blog post, which the Python documentation about super()
links to, doesn't mention anything about using **kwargs
and the ABC
module. It's focused on multiple inheritance with concrete classes. To rephrase my question, does the advice about using **kwargs
with super()
apply to classes that use the ABC
module?
For example:
from abc import ABC
class GameWeapon(ABC):
def __init__(self, name, damage, **av):
super().__init__(**av)
self.name = name
self.required_strength = required_strength
self.damage = damage
class ChargeGun(GameWeapon):
def __init__(self, name, required_strength, damage, **av):
super().__init__(name=name,damage=damage,**av)
Let's take a look at the particular instance in the blog post you refer to.
class Shape:
def __init__(self, shapename, **kwds):
self.shapename = shapename
super().__init__(**kwds)
class ColoredShape(Shape):
def __init__(self, color, **kwds):
self.color = color
super().__init__(**kwds)
cs = ColoredShape('red', shapename='circle', radius=30)
TypeError: object.__init__() takes no arguments
When we create a ColoredShape
object, it will require us to input the color and the shapename. If you pass an unexpected keyword argument, it will give you an error. This is because all classes by default (in python 3) inherit from the built-in type object
, which has an __init__
that expects no arguments.
As the article pointed out, object
is guaranteed to be the last class called in the MRO. However if you remove the call to super in Shape, you can add any number of keyword arguments without issue, even though they won't be used for anything.
class Shape:
def __init__(self, shapename, **kwds):
self.shapename = shapename
class ColoredShape(Shape):
def __init__(self, color, **kwds):
self.color = color
super().__init__(**kwds)
cs = ColoredShape('red', shapename='circle', radius=30, diameter=60)
In your code that you posted, you are inheriting from abc, which does not make a final call to Object's init via super. So the design pattern that is being shown in the blog post, does not apply in your case. I hope this helps.