Method resolution procedure in case of base classes Having different initialization parameters

I am trying to understand MRO in Python. Although there are different posts here, I don’t particularly get what I want. Consider two classes Aand Bobtained from BaseClass, each of which has __init__, taking different parameters.

class BaseClass(object):
    def __init__(self):
        print "I am the base class"

class A(BaseClass):
    def __init__(self, something, anotherthing):
        super(A, self).__init__()
        self.something = something
        self.anotherthing = anotherthing
    def methodsA(self):
        ...

class B(BaseClass):
    def __init__(self, someOtherThing):
        super(B, self).__init__()
        self.someOtherThing = someOtherThing 
    def methodsB(self):
        ...

Question: if I need to get the third class Cfrom both A, and Bhow do I initialize __init__if I need? I can safely output Cfrom Bor A.

   class C(A,B):
     def __init__(self, something, anotherthing, someOtherThing):
         super(C, self).__init__(something, anotherthing, someOtherThing)

The above implementation gives me an error.

+3
source share
5 answers

jonrsharpe , , **kwargs .

class BaseClass(object):
    def __init__(self, **kwargs):
        print("BaseClass.__init__({},{})".format('', kwargs))
        super(BaseClass,self).__init__(**kwargs)            

class A(BaseClass):
    def __init__(self, **kwargs):
        print("A.__init__({},{})".format('', kwargs))

        a = kwargs.pop('something')
        super(A,self).__init__(**kwargs)

class B(BaseClass):
    def __init__(self, **kwargs):
        print("B.__init__({},{})".format('', kwargs))       

        b = kwargs.pop('anotherthing')
        super(B,self).__init__(**kwargs)


class C(A, B):
    def __init__(self, **kwargs):
        print("C.__init__({},{})".format('', kwargs))

        super(C,self).__init__(**kwargs)


c = C(something=1,anotherthing='a')

, , named, kwargs.

, *args, , TypeError, .

EDIT:

, , , , . , , :

BaseClass .

, , MRO , BaseClass , super. :

object.__init__()

(BaseClass ) , , kwargs .

, , __init__ . , , .

( google) :

+1

, - :

class BaseClass(object):
    def __init__(self):
        print("BaseClass.__init__")

class A(BaseClass):
    def __init__(self):
        print("A.__init__")
        super(A, self).__init__()

class B(BaseClass):
    def __init__(self):
        print("B.__init__")
        super(B, self).__init__()

class C(A, B):
    def __init__(self):
        print("C.__init__")
        super(C, self).__init__()

:

>>> c = C()
C.__init__
A.__init__
B.__init__
BaseClass.__init__

, super: , . C A B, __init__ , BaseClass, __init__ , .

__init__ (, *args, **kwargs), TypeError, . , , .

0

, super . " ":

class C(A,B):
    def __init__(self, something, anotherthing, someOtherThing):
        A.__init__(self, something, anotherthing)
        B.__init__(self, someOtherThing)
0

bj0 , kwargs , . , , .

- **kwargs, - . object (BaseClass base), , :

class BaseClass(object):
    def __init__(self, **kwargs):
        super(BaseClass, self).__init__(**kwargs) # always try to pass on unknown args

class A(BaseClass):
    def __init__(self, something, anotherthing, **kwargs): # take known arguments
        super(A, self).__init__(**kwargs) # pass on the arguments we don't understand
        self.something = something
        self.anotherthing = anotherthing

class B(BaseClass):
    def __init__(self, someOtherThing, **kwargs): # same here
        super(B, self).__init__(**kwargs) # and here
        self.someOtherThing = someOtherThing 

class C(A, B): # this will work, with someOtherThing passed from A.__init__ to B.__init__
    pass

class D(B, A): # this will also work, with B.__init__ passing on A.__init__ arguments
    pass

import threading
class E(C, threading.Thread): # keyword arguments for Thread.__init__ will work!
    def run(self):
        print(self.something, self.anotherthing, self.someOtherThing)

( ) , , :

class F(C):
    def __init__(self, something, **kwargs):
        super(F, self).__init__(something="foo"+something, **kwargs)

, . :

f = F(something="something", anotherthing="bar", someOtherThing="baz")

- , , . , (, *args), , *args __init__ , , - , , , , .

0

, MRO. . , .

class BaseClass ():

    def __init__(self, *args, **kwargs):
        self.name = kwargs.get('name')

    def printName(self):
        print "I am called from BaseClass"
        print self.name

    def setName(self, givenName):
        print "I am called from BaseClass"
        self.name=givenName

    def CalledFromThirdGen(self):
        print "I am called from BaseClass and invoked from Third Generation Derived            Class"

FirstGenDerived (BaseClass):

    def __init__(self, *args, **kwargs):
        super(FirstGenDerived, self).__init__(*args, **kwargs)
        self.name = kwargs.get('name')
        self.FamilyName = kwargs.get('FamilyName')

    def printFullName(self):
        print "I am called from FirstDerivedClass"
        print self.name + ' ' + self.FamilyName

    def printName(self):
        print "I am called from FirstDerivedClass, although I was present in BaseClass"
        print "His Highness " + self.name + ' ' + self.FamilyName

SecondGenDerived (BaseClass):

    def __init__(self, *args, **kwargs):
        super(SecondGenDerived, self).__init__(*args, **kwargs)
        self.name = kwargs.get('name')
        self.middleName = kwargs.get('middleName')
        self.FamilyName = kwargs.get('FamilyName')

    def printWholeName(self):
        print "I am called from SecondDerivedClass"
        print self.name + ' ' + self.middleName + ' ' + self.FamilyName

    def printName(self):
        print "I am called from SecondDerivedClass, although I was present in BaseClass"
        print "Sir " + self.name + ' ' + self.middleName + ' ' + self.FamilyName

ThirdGenDerived (FirstGenDerived, SecondGenDerived):

    def __init__(self, *args, **kwargs):
        super(ThirdGenDerived, self).__init__(*args, **kwargs)

== " main":

    print "Executing BaseClass"
    BaseClass(name='Robin').printName()

    print "Executing Instance of BaseClass with SetName \n"
    Instance = BaseClass()
    Instance.setName("Little John")
    Instance.printName()
    print "################################################\n"


    print "Executing FirstGenDerived with printName and printFullName\n"
    FirstGenDerived(name='Robin', FamilyName='Hood').printFullName()
    FirstGenDerived(name='Robin', FamilyName='Hood').printName()
    print "################################################\n"


    print "Executing FirstGenderived with instance\n"
    Instance2 = FirstGenDerived(name=None, FamilyName="Hood")
    Instance2.setName("Edwards")
    Instance2.printFullName()
    print "################################################\n"

    print "Executing SecondGenDerived with printName and printWholeName\n"
    SecondGenDerived(name='Robin', FamilyName='Hood', middleName='Williams').printWholeName()
    SecondGenDerived(name='Robin', FamilyName='Hood', middleName='Williams').printName()
    print "################################################\n"

    print "Executing ThirdGenDerived\n"
    ThirdGenDerived(name='Robin', FamilyName='Hood', middleName='Williams').CalledFromThirdGen()
    ThirdGenDerived(name='Robin', FamilyName='Hood', middleName='Williams').printName()
    print "################################################\n"

: BaseClass BaseClass BaseClass SetName

BaseClass BaseClass

FirstGenDerived printName printFullName

FirstDerivedClass FirstDerivedClass, BaseClass

FirstGenderived

BaseClass FirstDerivedClass

SecondGenDerived print printWholeName

SecondDerivedClass SecondDerivedClass, BaseClass

ThirdGenDerived

I am being called from BaseClass and being called from a third-generation derived class I am being called from FirstDerivedClass, although I was present in BaseClass His Highness Robin Hood

-1
source

All Articles