Multiple inheritance: Interface problem workaround, please comment this

A

Axel Straschil

Hello!

I'm working on an HTML/Cgi widget's class where multiple inheritance
well be sometime a great thing.

I solved all my problems for pythons multiple inheritance with this ng,
thaks to all again, but there is one think I still dislike:

class A(object):
def __init__(self, a=None, **__eat):
print "A"
super(A, self).__init__()
class B(object):

def __init__(self, b=None, **__eat):
print "B"
super(B, self).__init__()

class AB(A, B):
def __init__(self, a=None, b=None):
super(AB, self).__init__(a=a, b=b)

ab = AB()

This looks (and I think is) correct, but I realy dislike the **__eat
stuff. As in python everything is virtual, I found no better solution to
do that. In my real world, i've got constucts like:
class A(object)
class B(A)
class AB(A,B)
(not realy so ugly like that ;-), just to say I can work only with super to
call __init__).

My problem: If you make a coding mistake, and the mistake does not give
a runtime error becouse **__eat is a hungry evil beast, it would be very
hard to debug ... think of a wrong written parameter!

So, here is my workaround, please comment this, if someone has a better
solution I would be glad:

class A(object):
def __init__(self, a=None, _do_eat=False, **__eat):
if __eat and not _do_eat: raise "I'm not hungry"
print "A"
super(A, self).__init__()

class B(object):
def __init__(self, b=None, _do_eat=False, **__eat):
if __eat and not _do_eat: raise "I'm not hungry"
print "B"
super(B, self).__init__()

class AB(A, B):
def __init__(self, a=None, b=None):
super(AB, self).__init__(a=a, b=b, _do_eat=True)

ab = AB()

Thanks,
AXEL.
 
S

Steven Bethard

Axel said:
I solved all my problems for pythons multiple inheritance with this ng,
thaks to all again, but there is one think I still dislike:

class A(object):
def __init__(self, a=None, **__eat):
print "A"
super(A, self).__init__()
class B(object):

def __init__(self, b=None, **__eat):
print "B"
super(B, self).__init__()

class AB(A, B):
def __init__(self, a=None, b=None):
super(AB, self).__init__(a=a, b=b)

ab = AB()
[snip]

My problem: If you make a coding mistake, and the mistake does not give
a runtime error becouse **__eat is a hungry evil beast, it would be very
hard to debug ... think of a wrong written parameter!

I also agree that this style is not pretty. What are A and B in your
real code? I would suggest that rather than this architecture, you
might do better to either:
(1) make A or B a mixin class that doesn't need __init__ called, or
(2) make class AB inherit from A and delegate to B (or vice versa)
For example:

py> class A(object):
.... def __init__(self, x):
.... self.x = x
....
py> class B(object):
.... def __init__(self, y):
.... self.y = y
....
py> class C(object):
.... def m(self):
.... return self.x, self.y
....
py> class ABC(A, C):
.... def __init__(self, x, y):
.... super(ABC, self).__init__(x)
.... self._b = B(y)
.... def __getattr__(self, name):
.... return getattr(self._b, name)
....
py> a = ABC(1, 2)
py> a.x
1
py> a.y
2
py> a.m()
(1, 2)

Note that A is the "true" superclass, B is delegated to, and C is just a
mixin class.

STeVe
 
A

Axel Straschil

Hello!
(1) make A or B a mixin class that doesn't need __init__ called, or

Would be a solution for classes that just give functionality, no
data-structures. In that case, i would use functions, no classes ;-)

I've seen code where there are classes without init and the hope that
self has what they expect, not realy the blackbox oop should produce!
(2) make class AB inherit from A and delegate to B (or vice versa)

As every multiple inheritance can be solved as single inheritance, if no
better solution for my "hungry monster problem" is found, this would be
the best way. Don't take my AB example as a real word example ;-)

Also think of to libraries with classes which have inheritance depth
five or more (that's what I've got). Somtimes you want to stick things
together without knowing the inheritance tree.

So, if there are ready class-modules, and I want to use them for
multiple inheritance, I've to rewrite the init's of classes in the
module!

For me, python is the best solution in oop-webprogramming (tried perl,
got ugly code, tried php, got php ;-), tried C++, takes too long for web
projects). The only thing I'm dislike is the super thing with multiple
inheritance, maby I shoud see pythons multiple inheritance as a nice to
have and not to use thing ;-)

Thanks,
AXEL.
 
M

Michele Simionato

Axel:
So, if there are ready class-modules, and I want to use them for
multiple inheritance, I've to rewrite the init's of classes in the
module!

Or you use a metaclass that rewrites the __init___ method for you.

This is a start (warning: written in 5 minutes and not tested more than
you see):

"""Given a hierarchy, makes __init__ cooperative.
The only change needed is to add a line

__metaclass__ = CooperativeInit

to the base class of you hierarchy."""

from decorate import decorate # see today thread on decorators for this

def make_cooperative_init(cls, name, bases, dic):

def call_cooperatively(__init__, self, *args, **kw):
super(cls, self).__init__(*args, **kw)
__init__(self, *args, **kw)

__init__ = cls.__dict__.get("__init__")
if __init__:
cls.__init__ = decorate(__init__, call_cooperatively)

class CooperativeInit(type):
__init__ = make_cooperative_init

class Base:
__metaclass__ = CooperativeInit
def __init__(self):
print "B.__init__"

class C1(Base):
def __init__(self):
print "C1.__init__"

class C2(Base):
def __init__(self):
print "C2.__init__"

class D(C1, C2):
def __init__(self):
print "D.__init__"




D()

# you get
# B.__init__
# C2.__init__
# C1.__init__
# D.__init__


Michele Simionato
 
A

Axel Straschil

Hello!
from decorate import decorate # see today thread on decorators for this

Gives me an ImportError: No module named decorate. I've got to donwload
that? (python 2.4)

Thanks,
AXEL.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top