need help on sublcass and scope

Peter Otten __peter__ at web.de
Tue Dec 9 05:55:58 EST 2003


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__(self, 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.





More information about the Python-list mailing list