[Numpy-discussion] ndarray.__mul__ is too gready?
Eike Welk
eike.welk@gmx....
Thu Apr 24 17:21:37 CDT 2008
Just for the record, because I had a very similar problem:
On Wednesday 23 January 2008 12:11, Pearu Peterson wrote:
> Users may accidentally hit vector * matrix and this should raise
> an exception. But when vector is numpy array, then ndarray.__mul__
> calls element * A for each array element and here A.__rmul__
> gets only the types of array elements (that are floats, for
> instance) as rhs and hence is not able to decide that it should
> return NotImplemented. Instead, it computes scalar * matrix and
> the final result will be
> array([element1*matrix, element2*matrix, ..])
> which is not desired already because of the memory usage and
> should have raised an exception instead.
>
> Here is a small example illustrating the problem:
>
> class A:
> def __rmul__(self, other):
> if isinstance(other, ndarray):
> return NotImplemented
> if isinstance(other, (int, float)):
> return self # pretend other==1 for an example
> return NotImplemented
>
> def __repr__(self): return 'A()'
>
> >>> array([1,2,3]) * A()
>
> array([A(), A(), A()], dtype=object)
> # expected TypeError
>
> Is there any workaround to this problem?
> In other situations/applications the above behavior of
> ndarray.__mul__ is a feature but is there any way to
> avoid this feature?
>
The class attribute __array_priority__ seems to control what exactly
happens when those special functions are called. It is said to be
documented in Travis Oliphant's Numpy book. Writing
__array_priority__ = 10.0 should do what you want.
So, the class definition should look like this:
class A(object):
__array_priority__ = 10.0
def __rmul__(self, other):
... <smart code here> ...
> Thanks,
> Pearu
Kind regards,
Eike.
More information about the Numpy-discussion
mailing list