新しい拡張タイプを書いていますが、数値演算 (加算/減算/乗算など) の設定に問題があります。通常の操作は呼び出されませんが、いくつかのインプレース操作を設定することができました。
たとえば、次の関数があります。
static PyObject *
MyType_Mul(PyObject *v, PyObject *w)
{
PyErr_SetString(PyExc_ValueError, "testing");
return NULL;
}
そして、次のように数値メソッドで設定しました。
static PyNumberMethods my_type_as_number = {
0, /* nb_add */
0, /* nb_sub */
(binaryfunc)MyType_Mul, /* nb_mul */
...
0, /* nb_in_place_add */
0, /* nb_in_place_sub */
(binaryfunc)MyType_Mul, /* nb_in_place_mul */
...
};
今、自分のタイプを使用しようとすると、次のような動作が発生します。
>>> from mytype import MyType
>>> a = MyType()
>>> a * 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'mytype.MyType' and 'int'
>>> 2 * a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'int' and 'mytype.MyType'
しかし、インプレース演算子を使用すると:
>>> a *= 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: testing
dir()
オブジェクトで使用すると、メソッド__mul__
と__rmul__
メソッドが表示されます(つまり、python がそれらを表示することを意味します)が、それらはまったく呼び出されないようです。a.__mul__(2)
リターンの使用NotImplemented
。
また:
>>> a.__mul__
<method-wrapper '__mul__' of mytype.MyType object at 0x7fc2ecc50468>
>>> a.__imul__
<method-wrapper '__imul__' of mytype.MyType object at 0x7fc2ecc50468>
ご覧のとおり、これらはまったく同じものです。
どうしたの?同じ正確な関数がインプレース演算子では機能するのに、「通常の」演算子では機能しないのはなぜですか? 間違ったスロットを使用したのではないかと思いましたが、再確認したところ正しく、 などに設定してもnb_add
機能nb_sub
しません。