[SciPy-dev] Suppressing of numpy __mul__, __div__ etc

Robert Kern robert.kern@gmail....
Sat Dec 12 15:16:58 CST 2009

On Sat, Dec 12, 2009 at 14:56, Charles R Harris
<charlesr.harris@gmail.com> wrote:
> 2009/12/12 Dmitrey <tmp50@ukr.net>
>> hello all,
>> I have class oofun (in a package FuncDesigner, that is already used by
>> lots of people) where some operations on numpy arrays (along with Python
>> lists and numbers) are overloaded, such as __mul__, __add__, __pow__,
>> __div__ etc.
>> There is a problem with numpy arrays: if I use a*f where a is array and f
>> is oofun, it returns array with elements a[i]*f. Would it omit calling
>> array.__mul__ and call only oofun.__rmul__, like it is done in numpy.matrix
>> and Python lists/numbers, all would work ok as expected; but now it makes
>> FuncDesigner code to work much slower or unexpectedly or doesn't work at all
>> instead.
>> So, does anyone mind if I'll commit some changes to numpy __mul__, __div__
>> etc?
>> I intend to implement the following walkaround:
>> Now the code looks like this for array:
>>     def __mul__(self, i):
>>         return asarray(multiply(self, i))
>> and like this for numpy/matrixlib/defmatrix.py:
>>     def __mul__(self, other):
>>         if isinstance(other,(N.ndarray, list, tuple)) :
>>             return N.dot(self, asmatrix(other))
>>         if isscalar(other) or not hasattr(other, '__rmul__') :
>>             return N.dot(self, other)
>>         return NotImplemented
>> and I want to add an empty class named "CNumpyLeftOperatorOverloaded" to
>> numpy, and if someone defines his class as a child of the one, __mul__ and
>> others will not invoke __div__ etc, calling otherClass.__rdiv__ etc:
>>     def __mul__(self, i):
>>         return asarray(multiply(self, i)) if not
>> isinstance(i,CNumpyLeftOperatorOverloaded) else i.__rmul__(self)
>> and declare my class as a child of the one.
>> As far as I understood, the changes should be added to
>> numpy/core/defcherarray.py
>> So, does anyone mind me to implement it?
>> D.
> Sounds like you are exporting an array interface or subclassing ndarray. If
> the latter, you might be able to manipulate the value of __array_priority__.
> I haven't experimented with these things myself.

I don't think he's subclassing ndarray, but does have a class that
shouldn't be interpreted by ndarray as a scalar. In any case,
__array_priority__ doesn't matter; it just controls which type the
output of a multi-input ufunc.

> As to the proposed solutions, they are the start of a slippery slope of
> trying to identify all objects to which they should apply. I don't think we
> want to go there.

I think what he is asking for is an empty mixin class which other
folks could subclass to mark their classes. It would say "Hey,
ndarray! Let my __mul__, __rmul__, etc., take priority over yours,
regardless of which of us comes first in the expression." Otherwise,
ndarray will gladly consume pretty much any object on the other side
of the operator because it will treat it as an object scalar.

We could also define a standard attribute that could mark such classes
instead of requiring a mixin subclass.

Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco

More information about the SciPy-Dev mailing list