2

I have two classes, with the same parameter initialized by their __init__ method. I would like to inherit both classes in class "X". But I will get: TypeError: B.__init__() missing 1 required positional argument: 'my_param'

Reproducible Example:

class A:
    def __init__(self, my_param):
        super().__init__()
        self.my_param = my_param


class B:
    def __init__(self, my_param):
        super().__init__()
        self.my_param = my_param * 2


class X(A, B):
    def __init__(self, my_param):
        super().__init__(my_param=my_param)

a = X(my_param=1)
print(a.my_param)

A and B are Mixins, they provide additional functionality for Child Classes. They can be used separetly or together. Lets's say class A provides searhc functionality for search by ID, where class B provides search by value.

Is there a way to set my_param for each of A and B or to set it without getting the error?

4
  • I would comment out super().__init__() call in A constructor method Commented Aug 26, 2022 at 15:02
  • X calls A with the parameter, but then A calls B without it. Your parent classes need to be written to collaborate in the inheritance. Commented Aug 26, 2022 at 15:02
  • so A and B are not related to each other? i.e. I assume it wouldn't make sense to inherit one from the other? Commented Aug 26, 2022 at 15:04
  • also, note that class Abstract is not used anywhere. Commented Aug 26, 2022 at 15:05

2 Answers 2

15

This can't be done just using super() calls, because the superclass of the last class in the chain will be object, which doesn't take a my_param parameter.

See python multiple inheritance passing arguments to constructors using super for more discussion of parameter passing to __init__() methods with multiple inheritance.

So you need to change X to call the superclass init methods explicitly, rather than using super(). And A and B shouldn't call super().__init__() because they're subclasses of object, which doesn't do anything in its __init__().

class A:
    def __init__(self, my_param):
        self.my_param = my_param

class B:
    def __init__(self, my_param):
        self.my_param = my_param * 2

class X(A, B):
    def __init__(self, my_param):
        A.__init__(self, my_param=my_param)
        B.__init__(self, my_param=my_param)
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer!, Unfortunately when I try this, I get the error: ´TypeError: object.__init__() takes exactly one argument (the instance to initialize)` I
ahhh, thank you so much for the explanation! I tried to solve it in the meantime by creating an abstract class shared by A and B but it feels not really clean, I definetly can use your solution and learned something new on the way, thank you again.
0

Since A and B share the same fields, I think it makes sense to make one inherit from the other - in this case, B inherit from A. That way, you'll only need to subclass from B in class X.

For example:

class A:
    def __init__(self, my_param):
        self.my_param = my_param


class B(A):
    def __init__(self, my_param):
        super().__init__(my_param * 2)
        # or:
        #   A.__init__(self, my_param * 2)


class X(B):
    def __init__(self, my_param):
        super().__init__(my_param=my_param)


a = X(my_param=1)
print(a.my_param)  # 2

3 Comments

This class hierarchy may not make sense for the rest of the behavior of B.
Totally right, I did make an assumption that since B and A share the same field, it might make sense to introduce some sort of inheritance. But I agree that this might not be the best idea, depending on the use case or scenario.
@rv.kvetch thank you for your answer, class A and B are Mixins, they provided different functunalities e.g. search by value (A) and search by id (B). Some childs of A and B only need A as parent, some only B and some both. But both classes share some attributes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.