Inyeol Lee wrote:
I'm an OOP newbie, and needs help on subclassing from different module.
I made a base module a.py which contains two classes C1 and C2;
[...]
but it looks like an ugly hack to me.
If there's common OOP idiom to handle this kind of problem, give me
some pointer.
I think with all these a, b and Cs, you raised the abstraction level too
high. To me - at least - it remains unclear what you are trying to achieve.
I've made a bold guess and tweaked your example to output what you expected
without having to mess with sys.modules.
#a.py
class C1(object):
def m(self):
print "method m in class C1 in module a"
class C2(object):
def __init__(self, a=None):
print "class C2 in module a"
if a is None: a = C1()
self.a = a
self.a.m()
#b.py
import a
class C1(a.C1):
def m(self):
print "method m in class C1 in module b"
a.C1.m(self)
class C2(a.C2):
def __init__(self):
print "class C2 in module b"
a.C2.__init__(s elf, C1())
If you want to modify a part of the C2 implementation independently of the
C2 hierarchy, you could make C1 a Mixin:
#a.py vs 2
class C1(object):
def m(self):
print "method m in class C1 in module a"
class C2(object):
def __init__(self, a=None):
print "class C2 in module a"
self.m()
#b.py vs 2
import a
class C1(a.C1):
def m(self):
print "method m in class C1 in module b"
super(C1, self).m()
class C2(a.C2, C1):
def __init__(self):
print "class C2 in module b"
super(C2, self).__init__( )
The beauty of this approach becomes visible if you add further subclasses to
C1:
#c.py aka b.py vs 3
import a
class C11(a.C1):
def m(self):
print "method m in class C11 in module c"
super(C11, self).m()
class C12(a.C1):
def m(self):
print "method m in class C12 in module c"
super(C12, self).m()
class C2(a.C2, C11, C12):
def __init__(self):
print "class C2 in module b"
super(C2, self).__init__( )
a.C1 occurs twice in the hierarchy, so how often would you expect
"method m in class C1 in module a" to be printed?
I you anser 1, then which of the following messages will be omitted:
"method m in class C11 in module c" or "method m in class C12 in module c"
Let's try:
import c
c.C2()
class C2 in module b
class C2 in module a
method m in class C11 in module c
method m in class C12 in module c
method m in class C1 in module a
<c.C2 object at 0x40295f0c>
Every m() was exactly called once!
However, I'm not an OOP newbie and still have doubts if I've got the above
right, so I would recommend the first approach. After all, Python is more
about readability and ease of use than clever tricks to confuse the
uninitiated.
Peter
PS: For more information, google for python and descrintro.