NumPy では、__array_priority__ 属性を使用して、ndarray およびユーザー定義型に作用する二項演算子を制御できます。例えば:
class Foo(object):
def __radd__(self, lhs): return 0
__array_priority__ = 100
a = np.random.random((100,100))
b = Foo()
a + b # calls b.__radd__(a) -> 0
ただし、同じことが比較演算子では機能しないようです。たとえば、次の行を に追加するFoo
と、式から呼び出されることはありませんa < b
。
def __rlt__(self, lhs): return 0
これは実際には Python の特別な名前ではないことに気付きました__rlt__
が、うまくいくかもしれないと思いました。__lt__
, __le__
, __eq__
, ,__ne__
のすべてを前に , plusを付けて、__ge__
または付けずに試してみましたが、NumPy にそれらのいずれかを呼び出すことはできませんでした。__gt__
r
__cmp__
これらの比較は上書きできますか?
アップデート
混乱を避けるために、ここでは NumPy の動作について詳しく説明します。手始めに、NumPy ガイドの本には次のように書かれています。
If the ufunc has 2 inputs and 1 output and the second input is an Object array
then a special-case check is performed so that NotImplemented is returned if the
second input is not an ndarray, has the array priority attribute, and has an
r<op> special method.
これが + を機能させるルールだと思います。次に例を示します。
import numpy as np
a = np.random.random((2,2))
class Bar0(object):
def __add__(self, rhs): return 0
def __radd__(self, rhs): return 1
b = Bar0()
print a + b # Calls __radd__ four times, returns an array
# [[1 1]
# [1 1]]
class Bar1(object):
def __add__(self, rhs): return 0
def __radd__(self, rhs): return 1
__array_priority__ = 100
b = Bar1()
print a + b # Calls __radd__ once, returns 1
# 1
ご覧のとおり、 がない__array_priority__
と、NumPy はユーザー定義オブジェクトをスカラー型として解釈し、配列内のすべての位置に操作を適用します。それは私が望むものではありません。私の型は配列のようなものです (ただし、ndarray から派生させるべきではありません)。
すべての比較メソッドが定義されている場合にこれがどのように失敗するかを示す長い例を次に示します。
class Foo(object):
def __cmp__(self, rhs): return 0
def __lt__(self, rhs): return 1
def __le__(self, rhs): return 2
def __eq__(self, rhs): return 3
def __ne__(self, rhs): return 4
def __gt__(self, rhs): return 5
def __ge__(self, rhs): return 6
__array_priority__ = 100
b = Foo()
print a < b # Calls __cmp__ four times, returns an array
# [[False False]
# [False False]]