Subclassing complex with computed arguments
Kent Johnson
kent3737 at yahoo.com
Fri Nov 26 00:06:59 EST 2004
Jp Calderone wrote:
> On 25 Nov 2004 14:30:18 -0800, pcolsen at comcast.net (Peter Olsen) wrote:
>
>>I want to define a class "point" as a subclass of complex.
>>
>>When I create an instance
>>
>>sample = point(<arglist>)
>>
>>I want "sample" to "be" a complex number, but with its real and
>>imaginary parts computed in point()'s __init__ function with their
>>values based on the arglist. I want to compute with point instances
>>as though they were native complex numbers, but I want to be able to
>>define some new methods and over-ride some of complex's existing ones.
>
> Something like this?
>
>>>>class simple(complex):
>
> ... def __new__(cls, real=0, imag=0):
> ... return super(simple, cls).__new__(cls, real + 1, imag + 1)
> ...
Unfortunately operations on 'simple' objects will return 'complex'
results. This is probably not what the OP wants.
>>> class point(complex):
... def __new__(cls, x, y):
... return complex.__new__(point, x*2, y*2)
...
>>> p=point(1,2)
>>> p
(2+4j)
>>> type(p)
<class '__main__.point'>
>>> p2=p+1
>>> p2
(3+4j)
>>> type(p2)
<type 'complex'>
I don't know if there is an easy way around this. A brute force approach
might be to override __add__(), etc to return point objects instead of
complex - though I haven't been able to figure out how to do this. I tried:
def __add__(self, *args, **kwds):
val = complex.__add__(self, *args, **kwds)
return point(val)
but val is NotImplemented instead of the desired sum ??
I had more luck with a delegation-based approach:
class point(object):
def __init__(self, *args, **kwds):
if len(args) == 1 and isinstance(args[0], complex):
self.c = args[0]
if len(args) == 2:
self.c = complex(args[0]*2, args[1]*2)
else:
self.c = complex(*args, **kwds)
def __add__(self, y):
val = self.c+y
return point(val)
def __repr__(self):
return 'point' + self.c.__repr__()
p=point(1,2)
print p
p1 = p+1
print p1
prints:
point(2+4j)
point(3+4j)
I was hoping that the special methods of point could delegate to the
corresponding special method of complex, so the delegation could be
automated, but again I couldn't get this to work. Maybe someone else can
explain this? For example if c is a complex number, why does
c.__add__(1) return NotImplemented?
I tried adding a delegating __coerce__() to class point but it is never
called...
Call me confused...
Kent
>
>>>>simple(3, 4)
>
> (4+5j)
>
>
> The trick is that since complex instances are immutable, you need to change the initialization parameters before the instance is ever created. __new__ is the hook for that.
>
> Jp
More information about the Python-list
mailing list