conditional __init__

Carl Banks pavlovevidence at gmail.com
Mon Nov 2 17:59:34 EST 2009


On Nov 2, 11:40 am, King <animator... at gmail.com> wrote:
> class A(object):
>     def __init__(self):
>         pass
>     def printme(self):
>         print "I am A"
>
> class B(object):
>     def __init__(self):
>         pass
>     def printme(self):
>         print "I am B"
>
> class K(A, B):
>     def __init__(self, value=0):
>         if value == 0:
>             A.__init__(self)
>             print "__init__ A"
>         elif value == 1:
>             B.__init__(self)
>             print "__init__ B"
>         self.printme()
>
> o = K(value=1)
>
> Output
>
> >>__init__ B
> >>I am A
>
> In above code "B" is correctly getting initialized as per condition.
> How ever method "printme" is printing "I am A".
> Instead it has to print "I am B" because "B" is the one that has been
> initialized. What's wrong here?

What's wrong is that you have a fundamental misunderstanding of what's
happening.  You can't just shut off a subclass by refusing to
initialize it--just doesn't work that way.  All subclasses will
continue to be active whether you call __init__ on them or not.
Therefore when you call self.printme() it searches the base classes in
order, and the first one it finds is A, so it always calls A's
printme.

It seems to me that you haven't learned enough about how inheritance
works in Python to use multiple inheritance yet, so I would suggest
just sticking to single inheritance for now, and study up.


> Is there a better/another way to do conditional initialization as
> needed above?

The fact that you feel the need to do this suggests that you want a
composition relationship, not an inheritance one.  What you appear to
be doing is defining a sort of "plugin", you have an object that can
behave one way (A) or another (B), but which one isn't known till run
time.  In that case the A or B object should be made an attribute of
the K object:

class A(object):
    def printme(self):
        print "I am A"

class B(object):
    def printme(self):
        print "I am B"

class K(object):
    def __init__(self, value=0):
        if value == 0:
            self.plugin = A()
            print "__init__ A"
        elif value == 1:
            self.plugin = B()
            print "__init__ B"
        self.plugin.printme()


Without seeing more of your code I strongly suspect that this change
better reflects what you're trying to do.


Carl Banks



More information about the Python-list mailing list