Cython中正确实现加减乘除运算符:解决_Point转Python对象错误
问题
我在.pxd文件中编写了如下代码:
_Point operator+(const _Point other) const _Point operator -(const _Point other) const bool operator==(const _Point other) const
在.pyx文件中,__eq__方法的实现如下,可正常运行:
def __eq__(self, Point other): cdef _Point* selfptr = self.c_point.get() cdef _Point* otherptr = other.c_point.get() return selfptr[0] == otherptr[0]
但在实现__add__这类运算符方法时,采用类似写法却报错:
def __add__(self, Point other): cdef _Point * selfptr = self.c_point.get() cdef _Point * otherptr = other.c_point.get() return selfptr[0] + otherptr[0]
错误信息如下:
× python setup.py egg_info did not run successfully. │ exit code: 1 ╰─> [27 lines of output] Error compiling Cython file: ------------------------------------------------------------ ... return not self.__eq__(other) def __add__(self, Point other): cdef _Point * selfptr = self.c_point.get() cdef _Point * otherptr = other.c_point.get() return selfptr[0] + otherptr[0] ^ ------------------------------------------------------------ src/Geometry/Point/Point.pyx:170:26: Cannot convert '_Point' to Python object
解决方案
报错原因很直接:Cython无法自动把C级别的_Point对象转换成Python可识别的对象,而__eq__返回的是bool类型,Cython可以自动完成bool到Python bool的转换,所以运行正常。
修复核心是手动把运算得到的_PointC对象包装成对应的Python类Point实例,具体步骤如下:
- 执行C级别的加法运算,得到
_Point类型的结果; - 实例化Python层面的
Point类,将C对象注入到实例中(需匹配你的Point类内部持有C对象的逻辑)。
修正后的__add__代码示例:
def __add__(self, Point other): cdef _Point * selfptr = self.c_point.get() cdef _Point * otherptr = other.c_point.get() # 执行C级加法,得到_Point对象 cdef _Point result_point = selfptr[0] + otherptr[0] # 创建Python层的Point实例 cdef Point result = Point() # 将C对象注入到Point实例中(这里假设c_point是智能指针,用reset持有新对象) result.c_point.reset(new _Point(result_point)) return result
注:具体的包装逻辑需要和你的Point类实现匹配,比如如果Point的构造函数支持直接传入_Point参数,也可以写成Point(result_point),只要确保最终返回的是Python可识别的Point实例即可。
内容的提问来源于stack exchange,提问作者Punreach Rany
相关产品推荐
相关产品推荐

