我正在编写一个新的扩展类型,但在设置数字运算(例如加法/减法/乘法)时遇到问题。我已经设法设置了一些就地操作,而没有调用正常操作。
例如,我有以下功能:
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__
and__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
也不起作用。