(Newbie) Restricting inherited methods to operate on element from same subclass

A

andy2o

Hi all,

Sorry if the post's title is confusing... I'll explain:

I have a class, called A say, and N>1 subclasses of A, called
A1, A2, A3, ..., AN say.

Instances of each subclass can sensibly be joined together with other
instances of the *same subclass*. The syntax of the join method is
identical for each of the N subclasses, so it would make sense to
implement a *single* method called join in the toplevel class A, and
then do:

a = A1()
b = A1()
a.join(b) #I want the join method to be inherited from class A

d = A2()
e = A2()
d.join(e)

But I want to raise an exception if my code finds:

f = A1()
g = A2()
f.join(g) #should raise exception, as cannot join an
#instance of A1 to an instance of A2.

How can I verify in a method defined in class A that the subclasses I
am joining are exactly the same? Or is there a design flaw here I
haven't spotted that makes this a bad idea? Or do I need to code N
join methods?

Many thanks,

Andy
 
D

Duncan Booth

andy2o said:
But I want to raise an exception if my code finds:

f = A1()
g = A2()
f.join(g) #should raise exception, as cannot join an
#instance of A1 to an instance of A2.

How can I verify in a method defined in class A that the subclasses I
am joining are exactly the same? Or is there a design flaw here I
haven't spotted that makes this a bad idea? Or do I need to code N
join methods?

Assuming that A is a new-style class then if they have to be exactly the
same type compare the types:

def join(self, other):
if type(self) != type(other):
raise whatever

if the 'other' value can be a subclass of self:

def join(self, other):
if not isinstance(other, type(self)):
raise whatever

If A is an old-style class then you would have to compare the __class__
attribute: self.__class__ != other.__class__
 
A

andy2O

Assuming that A is a new-style class then if they have to be
exactly the same type compare the types

Ah-ha! I didn't know that.
if the 'other' value can be a subclass of self:

def join(self, other):
if not isinstance(other, type(self)):
raise whatever

Simple and neat!
If A is an old-style class then you would have to compare
the __class__ attribute: self.__class__ != other.__class__

That answered my question perfectly. I'll read up on the new style
classes and pick whichever of your solutions fits best.

Many thanks,
Andy.
 
B

Bruno Desthuilliers

andy2o a écrit :
Hi all,

Sorry if the post's title is confusing... I'll explain:

I have a class, called A say, and N>1 subclasses of A, called
A1, A2, A3, ..., AN say.

Instances of each subclass can sensibly be joined together with other
instances of the *same subclass*. The syntax of the join method is
identical for each of the N subclasses, so it would make sense to
implement a *single* method called join in the toplevel class A, and
then do:

a = A1()
b = A1()
a.join(b) #I want the join method to be inherited from class A

d = A2()
e = A2()
d.join(e)

But I want to raise an exception if my code finds:

f = A1()
g = A2()
f.join(g) #should raise exception, as cannot join an
#instance of A1 to an instance of A2.

How can I verify in a method defined in class A that the subclasses I
am joining are exactly the same? Or is there a design flaw here I
haven't spotted that makes this a bad idea? Or do I need to code N
join methods?

You've already got the technical answer. About a possible design flaw,
it would seem to me that restricting the join() operation on specific
subclasses breaks the LSP. OTOH, Python being dynamically typed,
inheritence is merely an implementation detail, so that may not be such
a big deal after all... Anyway, you may want to document this point to
make it clear for the next person that'll have to work this code.

My 2 cents
 
A

andy2O

Bruno said:
You've already got the technical answer. About a possible design flaw,
it would seem to me that restricting the join() operation on specific
subclasses breaks the LSP. OTOH, Python being dynamically typed,
inheritence is merely an implementation detail, so that may not be such
a big deal after all... Anyway, you may want to document this point to
make it clear for the next person that'll have to work this code.

My 2 cents

OK, thanks - I see your point.

I was in effect implementing mutable objects, similar in some sense to
lists, by extending an immutable class similar to Python's tuples. I
think instead I should copy the Python type hierarchy, with the
list-like and tuple-like classes each defined as sub-classes of a
'sequence' class. In this case the type checking could go away.

I'm learning object-orientated programming and dynamic typed languages
the hard way at the moment, by trial and error. Can you, or anyone
suggest a good book which will guide me? Is there a classic text on
this? The coverage of OOP in 'Learning Python' is useful, but I could
do with something more in-depth.

Thanks again,
Andy.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top