Problem with operator overloading and inheritance in Python

Calvin Spealman ironfroggy at gmail.com
Mon Sep 18 00:21:16 EDT 2006


On 9/17/06, Edward A. Waugh <edward_waugh at hotmail.com> wrote:
>
>
>
>
> Consider the following code:
>
> import sys
>
> class FirstClass:
>     def __init__(self, value):
>         self.data = value
>     def __add__(self, value):
>         return FirstClass(self.data + value)
>     def display(self):
>         print self.data
>
> class SecondClass(FirstClass):
>     def __add__(self, value):
>         # Generalized version of SecondClass(self.data + value).
>         sum = FirstClass(self.data) + value
>         return SecondClass(sum.data)
>     def display2(self):
>         print self.data
>
> x = SecondClass(1)
> # Must reimplement __add__ in SecondClass or else x after the assignment is
> # an instance of class FirstClass not SecondClass.  This implies that all
> # subclasses of classes that overload operators such as + must reimplement
> # those methods to ensure that the class being returned is correct.
> x += 1
> x.display2()
>
> Note the comments in the code and observe that as is execution yields:
>
> C:\Files\Python> problem.py
> 2
>
> But if the reimplementation of __add__ in SecondClass is removed (or
> commented out) then as claimed in the comment above the code does not work:
>
> C:\Files\Python> problem.py
> Traceback (most recent call last):
>   File "C:\Files\Python\problem.py", line 25, in ?
>     x.display2()
> AttributeError: FirstClass instance has no attribute 'display2'
>
> This is because x after the statement x += 1 has been executed is an object
> of class FirstClass because the method implementing addition in FirstClass
> explicitly returns a FirstClass object.
>
> This seems to me to be a big problem because what this means is that if
> class X overloads any operator, e.g. addition, then all subclass of X (and
> all subclasses of those subclasses recursively)
> must reimplement all the operator methods defined in X.
>
> Is this a real problem with Python or just the way I am coding it as I admit
> that I am new to Python?
> If its my fault then what is the correct way to implement SecondClass?
>
> Thanks,
> Edward
>
> P.S. Why were slices ([low:high]) implemented to return the low'th to
> high-1'th values of a sequence?  For example I would expect that [2:4] of
> "abcdef" would return "cde" not "cd" and this is the case in other languages
> that do support slices of strings (HP BASIC) and arrays (Perl).  But I do
> accept that this a personal preference of mine so if folks don't agree with
> me that is fine.

You can take type(self) as the constructor for the result in the
__add__ method, as is shown in the example below. This will cause all
results to be of the same type as the left-hand operand in A+B for
this class' instances. Of course, this means you have to be sure that
all child classes take the same __init__ args, but that isn't hard to
stick to.

def __add__(self, value):
    return type(self)(self.data + value)



More information about the Python-list mailing list