6

I have a class:

class A(object):
    def __init__(self, *args):
        # impl

Also a "mixin", basically another class with some data and methods:

class Mixin(object):
    def __init__(self):
        self.data = []

    def a_method(self):
        # do something

Now I create a subclass of A with the mixin:

class AWithMixin(A, Mixin):
    pass

My problem is that I want the constructors of A and Mixin both called. I considered giving AWithMixin a constructor of its own, in which the super was called, but the constructors of the super classes have different argument lists. What is the best resolution?

mattbasta
  • 13,492
  • 9
  • 47
  • 68
muckabout
  • 1,923
  • 1
  • 19
  • 31
  • 1
    What's to stop you from calling the two base classes' constructors (with their appropriate arguments) from `AWithMixin.__init__`? – NPE Jun 09 '11 at 15:08
  • This has already been answered in depth. See http://stackoverflow.com/a/6100595/763269 – Chris Johnson Apr 06 '17 at 20:54

2 Answers2

10
class A_1(object):
    def __init__(self, *args, **kwargs):
        print 'A_1 constructor'
        super(A_1, self).__init__(*args, **kwargs)

class A_2(object):
    def __init__(self, *args, **kwargs):
        print 'A_2 constructor'
        super(A_2, self).__init__(*args, **kwargs)

class B(A_1, A_2):
    def __init__(self, *args, **kwargs):
        super(B, self).__init__(*args, **kwargs)
        print 'B constructor'

def main():
    b = B()
    return 0

if __name__ == '__main__':
    main()
  1. A_1 constructor
  2. A_2 constructor
  3. B constructor
kecske
  • 649
  • 1
  • 8
  • 19
9

I'm fairly new to OOP too, but what is the problem on this code:

class AWithMixin(A, Mixin):
    def __init__(self, *args):
        A.__init__(self, *args)
        Mixin.__init__(self)
mattbasta
  • 13,492
  • 9
  • 47
  • 68
utdemir
  • 26,532
  • 10
  • 62
  • 81
  • 2
    that is the best solution and I always use it. However, if both `A` and `Mixin` extends some class (e.g. `Base`) and both call `Base.__init__()` it can be mandatory to use the [super() function](http://stackoverflow.com/q/576169). It is complicated IMHO and I recommend to know but avoid it if possible. – brandizzi Jun 09 '11 at 15:37
  • @brandizzi, as I said on the answer, I'm new to OOP. I looked the super function, but didn't understand. If I said on this class [code]super(AWithMixin, self).__init__()[/code], how can I call A.__init__ and Mixin.__init__ both? And specify different arguments? – utdemir Jun 09 '11 at 17:10
  • 1
    The problem is that this solution isn't particularly extensible, and it completely ignores the point of encapsulation, and it specifies the mixin in the wrong order. If you Want to override methods in a mixin, then that mixin gets control over that method and should be responsible for calling the same method in a super class. The fact that the mixin takes a different argument list suggests that it's coded incorrectly/was not designed for use with this child class -- it's in violation of [LSP](http://en.wikipedia.org/wiki/Liskov_substitution_principle)). – quodlibetor Aug 29 '13 at 20:49