A.my_method
assumes that A
(or any subclass thereof) can be instantiated with a single argument. You broke that assumption by adding a required argument value
to B.__init__
. You'll need to make value
the second parameter, and make it optional.
class B(A):
def __init__(self, name, value=None):
super().__init__(name)
self.value = value
Whether it is useful to use A.my_method
to create an instance of B
with value=None
is another question.
Let's pretend you could change A
. Then it would be better to design it to facilitate subclassing in the first place.
class A:
def __init__(self, *, name, **kwargs):
super().__init__(**kwargs)
self.name = name
@classmethod
def my_method(cls, **kwargs):
# Note: passing an explicit name argument will
# result in a TypeError on multiple arguments for
# the keyword argument 'name'
return cls(name="Alice", **kwargs)
Now you could define B
as
class B(A):
def __init__(self, *, value, **kwargs):
super().__init__(**kwargs)
self.value = value
a1 = A(name="Bob")
a2 = A.my_method() # A(name="Alice")
b1 = B(name="Joe", value=5)
b2 = B.my_method(value=10) # B(name="Alice", value=10)
This uses advice from https://rhettinger.wordpress.com/2011/05/26/super-considered-super/ with regards to __init__
(and by extension, alternate class-method constructors):
- use keyword arguments when calling
- only handle your own parameters explicitly
- accept all unexpected keyword arguments to pass on to an ancestor class