2017-12-11 8 views
0

私はクラスCustomArraynumpy.ndarrayに似ています。それは__add__,__mul__などの算術演算子の束を過負荷にします。人々はnumpyと組み合わせて使用​​する可能性が高いので、時々numpy.ndarrayの演算子がCustomArrayの代わりに呼び出されることが恐れられます。最悪の事は、彼らが実際に働き、望ましくない結果を生み出すことです。pythonはオペレータコールを防ぎます

a = np.array([1, 2, 3]) 
b = CustomArray([1, 2, 3]) 
c = a + b # np.ndarray.__add__ will be called! 

これを防止する手段はありますか?したがって、インタプリタはエラーを発生させるか、常にCustomArray演算子のオーバーロードを優先します。

+1

類似した最近の質問(回答はありません):https://stackoverflow.com/questions/47600049/can-binary-operator-methods-of-numpy-arrays-be-overridden-by-the-right-operand – hpaulj

+0

いいえ、ありません。左側のオペランドがメソッドを実装している場合は、最初に実行されます。 – jonrsharpe

+0

@jonrsharpe mb 'CustomArray'を修正してnumpyが妥当なエラーメッセージを生成する方法があります。 – DikobrAz

答えて

2

NumPy 1.13には、新しい__array_ufunc__ APIがあります。このAPIは暫定であり、下位互換性は保証されていません。

numpy.ndarray NumPy ufuncsを演算子に委譲し、NumPy ufuncsは__array_ufunc__に委譲してufuncの動作を実装します。このルールはnumpy.ndarray.__array_ufunc__をスキップするので、独自の__array_ufunc__を実装する場合は、NumPy配列でインスタンスを使用するときは常に優先されます。

あなたは、オブジェクトのすべてのufuncsを無効にしたい場合は、あなたのクラスに__array_ufunc__ = Noneを設定することができます。

class CustomArray(...): 
    __array_ufunc__ = None 

をあなたはそれを実装したい場合は別の方法として、署名は

def __array_ufunc__(self, ufunc, method, *inputs, **kwargs) 

です興味がある場合は、

  • ufuncはufuncオブジェクトです(for +たとえば、numpy.add)、
  • method
  • inputsタプル(left operand, right operand)であり、
  • kwargsが空である、"__call__"あります。
より高度な例については

methodinputs、およびkwargsは異なる場合がありますので、return NotImplementedあなたはこれらのケースに対処したくない場合。あなたがnumpyのアレイと+をオーバーロードしたい場合は

例として、あなたはまた、まだ__add__を実装する必要があります

def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): 
    if ufunc is not numpy.add: 
     return NotImplemented 
    if method != "__call__": 
     return NotImplemented 
    if kwargs: 
     return NotImplemented 
    return my_addition_logic(*inputs) 

を書くことができます。

+0

何らかの理由で正常に動作しない場合は、np.ndarrayからサブクラス化した場合にのみ動作しますか? – DikobrAz

+0

@DikobrAz:いいえ、 'numpy.ndarray'をサブクラス化するのは特に必須ではありません。 – user2357112

+0

それは働いて、ありがとう! – DikobrAz

関連する問題