Extending: overloading operators (e.g. for a vector class)

Bernhard Herzog bh at intevation.de
Thu May 23 06:45:02 EDT 2002


Chris Liechti <cliechti at gmx.net> writes:

> say i have the follwing class (details ommited):
> 
> class Vector2D:
>     def __init__(self, x=0, y=0):
>         self.x, self.y = x, y
>     ...
>     def __mul__(self, other):
>         if type(other) in (int, float):
>             return Vector2D( self.x*other, self.y*other )
>         else:
>             raise NotImplementedError
> 
> now i want to program this as a C extension type (for practise, i know that 
> there are existing extensions to represent a vector).

You may want to have a look at Sketch, perhaps. It implements exactly
this. A 2D vector/point as a C extension type.

Implementing sequence and number interfaces in the same C extension type
is not all that easy, but it's become much better with the "newstyle
numbers" in Python 2.1.

> it seems to me tp_as_number supports __mul__ for numbers, but only for 
> instances of the same type, a coercion function (nb_coerce) can help in 
> some cases (e.g. converting a complex), but i can't use it to represent a 
> scalar (int, long, float) in this case.

In Python 2.1 and higher this is relatively simple. If you use "newstyle
numbers" python won't attempt a coercion and call the nb_multiply method
directly with the operands.

> and there seems so be an other place where a __mul__ can be emulated: 
> sq_repeat for sequences. can/must i define both, or none?

AFAICT, in Python 2.1 and 2.2 sq_repeat will never be called by the
interpreter itself, but it might be called by other C code which calls
PySequence_Repeat. Make me wonder whether it should be deprecated :)

In older versions -- at least in 1.5.2 haven't 2.0 -- Python special
cased the * operator quite a bit. For instance if you mutliplied a
sequence with an int it called the sequence's repeat implementation
regardless of the order of the operands!

> should i provide these methods (__mul__, __add__ etc.) throug getattr and 
> implement them just as i would do it when not overloading an operator (like 
> defining a .multiply(other) method but name it __mul__)?

I haven't looked at how Python 2.2 handles this sort of thing yet. In
earlier versions you do it by implementing the functions in
tp_as_number, etc, but as long as your type object is an instance of
PyType_Type you probably don't have to worry about these methods.

> i expect similar problems when using __add__ with a tuple/list etc.

In python 1.5.2 you had to implement addition of vectors in the
sq_repeat if you wanted to be able to use it as a sequence as well. In
2.1 the nb_add is tried before sq_concat, AFAICT.

   Bernhard

-- 
Intevation GmbH                                 http://intevation.de/
Sketch                                 http://sketch.sourceforge.net/
MapIt!                                           http://www.mapit.de/



More information about the Python-list mailing list