need help on sublcass and scope

I

Inyeol Lee

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;

## start of a.py

class C1(object):
def m(self):
print "method m in class C1 in module a"

class C2(object):
def __init__(self):
print "class C2 in module a"
self.a = C1()
self.a.m()

## end of of a.py

Then, I made another module b.py which extends this base module;

## start of 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)

## end of of b.py

When I instantiate C2, I get;
class C2 in module b
class C2 in module a
method m in class C1 in module a
It doesn't use class C1 in module 'b', but uses C1 in module 'a' because
the last line in b.py 'a.c2.__init__(self)' runs with module scope a.
So I tweaked the C1 instantiation line in a.py from

self.a = C1()

to

import sys
self.a = sys.modules[self.__module__].C1()

and got the result I expected;
class C2 in module b
class C2 in module a
method m in class C1 in module b
method m in class C1 in module a
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.

Thanks,
Inyeol
 
P

Peter Otten

Inyeol said:
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:
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

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.
 

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

Staff online

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top