Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > class inheritance

Reply
Thread Tools

class inheritance

 
 
JLundell
Guest
Posts: n/a
 
      03-13-2010
I've got a subclass of fractions.Fraction called Value; it's a mostly
trivial class, except that it overrides __eq__ to mean 'nearly equal'.
However, since Fraction's operations result in a Fraction, not a
Value, I end up with stuff like this:

x = Value(1) + Value(2)

where x is now a Fraction, not a Value, and x == y uses
Fraction.__eq__ rather than Value.__eq__.

This appears to be standard Python behavior (int does the same thing).
I've worked around it by overriding __add__, etc, with functions that
invoke Fraction but coerce the result. But that's tedious; there are a
lot of methods to override.

So I'm wondering: is there a more efficient way to accomplish what I'm
after?
 
Reply With Quote
 
 
 
 
Patrick Maupin
Guest
Posts: n/a
 
      03-13-2010
On Mar 13, 11:03*am, JLundell <(E-Mail Removed)> wrote:
> I've got a subclass of fractions.Fraction called Value; it's a mostly
> trivial class, except that it overrides __eq__ to mean 'nearly equal'.
> However, since Fraction's operations result in a Fraction, not a
> Value, I end up with stuff like this:
>
> x = Value(1) + Value(2)
>
> where x is now a Fraction, not a Value, and x == y uses
> Fraction.__eq__ rather than Value.__eq__.
>
> This appears to be standard Python behavior (int does the same thing).
> I've worked around it by overriding __add__, etc, with functions that
> invoke Fraction but coerce the result. But that's tedious; there are a
> lot of methods to override.
>
> So I'm wondering: is there a more efficient way to accomplish what I'm
> after?


7 years ago, I had a similar problem for a different and now obsolete
reason. I'm sure my solution could be easily updated though. I wrote
code to write a wrapper class. Sort of a meta-module. Original
reference here:

http://groups.google.com/group/comp....289c16603fb374

HTH,
Pat
 
Reply With Quote
 
 
 
 
Jack Diederich
Guest
Posts: n/a
 
      03-13-2010
On Sat, Mar 13, 2010 at 12:03 PM, JLundell <(E-Mail Removed)> wrote:
> I've got a subclass of fractions.Fraction called Value; it's a mostly
> trivial class, except that it overrides __eq__ to mean 'nearly equal'.
> However, since Fraction's operations result in a Fraction, not a
> Value, I end up with stuff like this:
>
> x = Value(1) + Value(2)
>
> where x is now a Fraction, not a Value, and x == y uses
> Fraction.__eq__ rather than Value.__eq__.
>
> This appears to be standard Python behavior (int does the same thing).
> I've worked around it by overriding __add__, etc, with functions that
> invoke Fraction but coerce the result. But that's tedious; there are a
> lot of methods to override.
>
> So I'm wondering: is there a more efficient way to accomplish what I'm
> after?


If Fraction.__add__ returns a new object but the subclass Value is
compatible (as I would except since it is a sublcass) then just change
all references in Franction.__add__ to be more generic, ex/

class Franction():
def __add__(self, other):
return self.__classs__(self.denominator + other.denominator)

That way if __add__ is called by an instance of a subclass it will
return an instance of that subclass.

-Jack
 
Reply With Quote
 
Patrick Maupin
Guest
Posts: n/a
 
      03-13-2010
On Mar 13, 11:37*am, Jack Diederich <(E-Mail Removed)> wrote:
> If Fraction.__add__ returns a new object but the subclass Value is
> compatible (as I would except since it is a sublcass) then just change
> all references in Franction.__add__ to be more generic, ex/
>
> class Franction():
> * def __add__(self, other):
> * * return self.__classs__(self.denominator + other.denominator)
>
> That way if __add__ is called by an instance of a subclass it will
> return an instance of that subclass.
>


Yes, I think the OP understands that, and also understands that he
would have to do the same thing for __sub__, __div__, __rsub__,
__radd__, etc.

That's why I suggested that, instead of writing all that tedious code,
he could write code that writes the tedious code

As Terence Parr of ANTLER fame asks: "Why program by hand in five
days what you can spend five years of your life automating?"

Pat
 
Reply With Quote
 
JLundell
Guest
Posts: n/a
 
      03-13-2010
On Mar 13, 9:37*am, Jack Diederich <(E-Mail Removed)> wrote:
> If Fraction.__add__ returns a new object but the subclass Value is
> compatible (as I would except since it is a sublcass) then just change
> all references in Franction.__add__ to be more generic, ex/
>
> class Franction():
> * def __add__(self, other):
> * * return self.__classs__(self.denominator + other.denominator)
>
> That way if __add__ is called by an instance of a subclass it will
> return an instance of that subclass.


That was my first thought, because I had originally assumed that's the
way Fraction worked. However, a) it's easier to do the overriding in
my own class than patching Fraction (or at least no harder), and 2)
Fraction is only doing the same thing that int does, so it's hard to
justify a patch.

I think Patrick's solution might be the tidiest one. I'll give it a
shot (thanks, Patrick).
 
Reply With Quote
 
Carl Banks
Guest
Posts: n/a
 
      03-13-2010
On Mar 13, 9:03*am, JLundell <(E-Mail Removed)> wrote:
> I've got a subclass of fractions.Fraction called Value; it's a mostly
> trivial class, except that it overrides __eq__ to mean 'nearly equal'.
> However, since Fraction's operations result in a Fraction, not a
> Value, I end up with stuff like this:
>
> x = Value(1) + Value(2)
>
> where x is now a Fraction, not a Value, and x == y uses
> Fraction.__eq__ rather than Value.__eq__.
>
> This appears to be standard Python behavior (int does the same thing).
> I've worked around it by overriding __add__, etc, with functions that
> invoke Fraction but coerce the result. But that's tedious; there are a
> lot of methods to override.
>
> So I'm wondering: is there a more efficient way to accomplish what I'm
> after?


It's a tad unfortunately Python doesn't make this easier. If I had to
do it more than once I'd probably write a mixin to do it:

class ArithmeticSelfCastMixin(object):
def __add__(self,other):
return
self.__class__(super(ArithmeticSelfCastMixin,self) .__add__(other)
# etc.


class Value(ArithmeticSelfCastMixin,fraction.Fraction):
pass


However, I want to warn you about overriding __eq__ to mean "almost
equal": it can have unexpected results so I don't recommend it. Two
of the main issues with it are:

1. It violates the transitive property ("If A == B and B == C, then A
== C") which most programmers expect to be true.

2. It will give unpredictable results when the objects are used in
sets or as dictionary keys. Those thow types expect the transitive
property to be true. If you are going to redefine __eq__ to mean
"almost equal", then at least define __hash__ to raise
NotImplementedError so that Python will refuse to use them in sets or
as dictionary keys:

def __hash__(self): raise NotImplementedError


Carl Banks
 
Reply With Quote
 
Jean-Michel Pichavant
Guest
Posts: n/a
 
      03-15-2010
JLundell wrote:
> I've got a subclass of fractions.Fraction called Value; it's a mostly
> trivial class, except that it overrides __eq__ to mean 'nearly equal'.
> However, since Fraction's operations result in a Fraction, not a
> Value, I end up with stuff like this:
>
> x = Value(1) + Value(2)
>
> where x is now a Fraction, not a Value, and x == y uses
> Fraction.__eq__ rather than Value.__eq__.
>
> This appears to be standard Python behavior (int does the same thing).
> I've worked around it by overriding __add__, etc, with functions that
> invoke Fraction but coerce the result. But that's tedious; there are a
> lot of methods to override.
>
> So I'm wondering: is there a more efficient way to accomplish what I'm
> after?
>

I would change the approach.
To the question, "*is* a Value a Fraction", some may tempted to answer
"No" (for instance, a fraction has a denominator, a value has not).
However "Does a Fraction *have* a Value", you could possibly say "Yes".

The value may be then an attribute of the class Fraction, not a subclass.
To test fraction equality, use F1 == F2. In order to test 'nearly
equality', use F1.val() == F2.val().

JM




 
Reply With Quote
 
JLundell
Guest
Posts: n/a
 
      03-15-2010
On Mar 13, 1:26*pm, Carl Banks <(E-Mail Removed)> wrote:
> It's a tad unfortunately Python doesn't make this easier. *If I had to
> do it more than once I'd probably write a mixin to do it:
>
> class ArithmeticSelfCastMixin(object):
> * * def __add__(self,other):
> * * * * return
> self.__class__(super(ArithmeticSelfCastMixin,self) .__add__(other)
> * * # etc.
>
> class Value(ArithmeticSelfCastMixin,fraction.Fraction):
> * * pass
>
> However, I want to warn you about overriding __eq__ to mean "almost
> equal": it can have unexpected results so I don't recommend it. *Two
> of the main issues with it are:
>
> 1. It violates the transitive property ("If A == B and B == C, then A
> == C") which most programmers expect to be true.
>
> 2. It will give unpredictable results when the objects are used in
> sets or as dictionary keys. *Those thow types expect the transitive
> property to be true. *If you are going to redefine __eq__ to mean
> "almost equal", then at least define __hash__ to raise
> NotImplementedError so that Python will refuse to use them in sets or
> as dictionary keys:
>
> * * def __hash__(self): raise NotImplementedError
>
> Carl Banks


It's also unfortunate that Python doesn't have an approximately-equal
operator; it'd come in handy for floating-point applications while
preserving hash. If only there were a ~= or ≈ operator I could
overload. And ~ is unary, so no joy.

My application is in that sense a little like a floating-point app, in
that it needs approximately-equal. And it doesn't need Value to be
hashable; thanks for the NotImplementedError suggestion; I've done
that as a safeguard.

 
Reply With Quote
 
Carl Banks
Guest
Posts: n/a
 
      03-16-2010
On Mar 15, 4:34*pm, JLundell <(E-Mail Removed)> wrote:
> It's also unfortunate that Python doesn't have an approximately-equal
> operator; it'd come in handy for floating-point applications while
> preserving hash. If only there were a ~= or ≈ operator I could
> overload. And ~ is unary, so no joy.


One problem with it is that there's no way to make it universal;
different appiplications have different ideas of close. Conceivably
it could be usefully defined for a user type though..

Bacause of this problem almost no languages have an almost equal
operator. I'm curious what languages do, of if there are any with a
trinary operator that also takes a threshold.

Carl Banks
 
Reply With Quote
 
Dave Angel
Guest
Posts: n/a
 
      03-16-2010


Carl Banks wrote:
> On Mar 15, 4:34 pm, JLundell <(E-Mail Removed)> wrote:
>
>> It's also unfortunate that Python doesn't have an approximately-equal
>> operator; it'd come in handy for floating-point applications while
>> preserving hash. If only there were a ~=r ≈ operator I could
>> overload. And ~ is unary, so no joy.
>>

>
> One problem with it is that there's no way to make it universal;
> different appiplications have different ideas of close. Conceivably
> it could be usefully defined for a user type though..
>
> Bacause of this problem almost no languages have an almost equal
> operator. I'm curious what languages do, of if there are any with a
> trinary operator that also takes a threshold.
>
> Carl Banks
>
>

If I recall correctly, APL has a *fuzz* value, which is used in all(?)
comparisons. But I do not recall anything about how it was defined. I do
recall that you could change the threshold, and suspect it was relative
to the operands. For symmetry, it would probably have to be relative to
the average of the two values, or some such.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ Struct inheritance against class inheritance johnsonlau C++ 1 07-21-2008 04:58 PM
Private Inheritance and Publice Inheritance karthikbalaguru C++ 9 09-10-2007 01:05 PM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
mul. inheritance & overloading operator new/delete solved by virtual base inheritance? cppsks C++ 0 10-27-2004 07:49 PM
Private access modifier and Inheritance (Inheritance implementation in Java) maxw_cc Java 1 12-21-2003 11:38 AM



Advertisments