python – correct way to use super (argument passing)

python – correct way to use super (argument passing)

Sometimes two classes may have some parameter names in common. In that case, you cant pop the key-value pairs off of **kwargs or remove them from *args. Instead, you can define a Base class which unlike object, absorbs/ignores arguments:

class Base(object):
    def __init__(self, *args, **kwargs): pass

class A(Base):
    def __init__(self, *args, **kwargs):
        print A
        super(A, self).__init__(*args, **kwargs)

class B(Base):
    def __init__(self, *args, **kwargs):
        print B
        super(B, self).__init__(*args, **kwargs)

class C(A):
    def __init__(self, arg, *args, **kwargs):
        print C,arg=,arg
        super(C, self).__init__(arg, *args, **kwargs)

class D(B):
    def __init__(self, arg, *args, **kwargs):
        print D, arg=,arg
        super(D, self).__init__(arg, *args, **kwargs)

class E(C,D):
    def __init__(self, arg, *args, **kwargs):
        print E, arg=,arg
        super(E, self).__init__(arg, *args, **kwargs)

print MRO:, [x.__name__ for x in E.__mro__]
E(10)

yields

MRO: [E, C, A, D, B, Base, object]
E arg= 10
C arg= 10
A
D arg= 10
B

Note that for this to work, Base must be the penultimate class in the MRO.

If youre going to have a lot of inheritence (thats the case here) I suggest you to pass all parameters using **kwargs, and then pop them right after you use them (unless you need them in upper classes).

class First(object):
    def __init__(self, *args, **kwargs):
        self.first_arg = kwargs.pop(first_arg)
        super(First, self).__init__(*args, **kwargs)

class Second(First):
    def __init__(self, *args, **kwargs):
        self.second_arg = kwargs.pop(second_arg)
        super(Second, self).__init__(*args, **kwargs)

class Third(Second):
    def __init__(self, *args, **kwargs):
        self.third_arg = kwargs.pop(third_arg)
        super(Third, self).__init__(*args, **kwargs)

This is the simplest way to solve those kind of problems.

third = Third(first_arg=1, second_arg=2, third_arg=3)

python – correct way to use super (argument passing)

As explained in Pythons super() considered super, one way is to have class eat the arguments it requires, and pass the rest on. Thus, when the call-chain reaches object, all arguments have been eaten, and object.__init__ will be called without arguments (as it expects). So your code should look like this:

class A(object):
    def __init__(self, *args, **kwargs):
        print A
        super(A, self).__init__(*args, **kwargs)

class B(object):
    def __init__(self, *args, **kwargs):
        print B
        super(B, self).__init__(*args, **kwargs)

class C(A):
    def __init__(self, arg, *args, **kwargs):
        print C,arg=,arg
        super(C, self).__init__(*args, **kwargs)

class D(B):
    def __init__(self, arg, *args, **kwargs):
        print D, arg=,arg
        super(D, self).__init__(*args, **kwargs)

class E(C,D):
    def __init__(self, arg, *args, **kwargs):
        print E, arg=,arg
        super(E, self).__init__(*args, **kwargs)

print MRO:, [x.__name__ for x in E.__mro__]
E(10, 20, 30)

Leave a Reply

Your email address will not be published. Required fields are marked *