使用 Boost Python,我可以包装 C++ 重载运算符“+=”、“-=”、“*=”,但不能包装“/=”?
Using Boost Python, I can wrap C++ overloaded operators "+=", "-=", "*=", but not "/="?
Boost Python 有一个非常简单的包装重载运算符的方法。在 boost.org (https://www.boost.org/doc/libs/1_66_0/libs/python/doc/html/tutorial/tutorial/exposing.html) 公开 C++ classes、方法等的教程给出了这个例子:
示例的重载 C++ 运算符 class,FilePos:
class FilePos { /*...*/ };
FilePos operator+(FilePos, int);
FilePos operator+(int, FilePos);
int operator-(FilePos, FilePos);
FilePos operator-(FilePos, int);
FilePos& operator+=(FilePos&, int);
FilePos& operator-=(FilePos&, int);
bool operator<(FilePos, FilePos);
如何将它们映射到 Python:
class_<FilePos>("FilePos")
.def(self + int()) // __add__
.def(int() + self) // __radd__
.def(self - self) // __sub__
.def(self - int()) // __sub__
.def(self += int()) // __iadd__
.def(self -= other<int>())
.def(self < self); // __lt__
我有一个名为“Angle”的 C++ class,它代表一个角度。它具有重载运算符,包括“+=”、“-=”、“*=”和“/=”。每个重载运算符都设计为将一些双精度类型的输入加、减、乘或除到角度 class 所持有的度值。 Angle class 包装器以与上例中描述的完全相同的方式映射这些重载运算符。当我测试 Python 中的加法、减法和乘法运算符时,它们运行得非常好。除法运算符,不是这样。当我 运行 像这样的简单测试时:
A = Angle(1) # instantiate Angle object with magnitude of 1 radian
A /= 2.0 # attempt to divide the radian measurement by 2
我收到以下错误:
TypeError: unsupported operand type(s) for /=: 'Angle' and 'float'
基于这个问题:
Error when trying to overload an operator "/"
我看到 Python3(我正在使用的版本)有一种独特的理解“/”字符的方式。但是,此解决方案对我不起作用,因为我使用的 class 是包装的 C++ class.
我的问题:有没有办法使用 boost 以保留相同语法的方式将重载运算符“/=”从 C++ 映射到 python(即不在 C++ 中编写名为执行相同操作但必须用“Angle.selfdiv()”) 调用的“selfdiv”?也许有一些方法可以覆盖 Python 解释正斜杠字符的方式?
Python 3 更改了除法运算符的定义方式,Boost.Python 的自动生成版本使用旧的 Python 2 样式进行就地除法,没有更长的作品。这似乎是一个疏忽,因为非就地版本已更新为 Python 3 的 __truediv__
魔术方法。关于这件事有一个open GitHub issue。在它得到修复之前,您可以像定义任何其他 class 成员函数一样定义 __itruediv__
and/or __ifloordiv__
:
class_<Foo>("Foo")
.def(
"__itruediv__",
&Foo::operator/=,
return_self<>{}
);
Boost Python 有一个非常简单的包装重载运算符的方法。在 boost.org (https://www.boost.org/doc/libs/1_66_0/libs/python/doc/html/tutorial/tutorial/exposing.html) 公开 C++ classes、方法等的教程给出了这个例子:
示例的重载 C++ 运算符 class,FilePos:
class FilePos { /*...*/ };
FilePos operator+(FilePos, int);
FilePos operator+(int, FilePos);
int operator-(FilePos, FilePos);
FilePos operator-(FilePos, int);
FilePos& operator+=(FilePos&, int);
FilePos& operator-=(FilePos&, int);
bool operator<(FilePos, FilePos);
如何将它们映射到 Python:
class_<FilePos>("FilePos")
.def(self + int()) // __add__
.def(int() + self) // __radd__
.def(self - self) // __sub__
.def(self - int()) // __sub__
.def(self += int()) // __iadd__
.def(self -= other<int>())
.def(self < self); // __lt__
我有一个名为“Angle”的 C++ class,它代表一个角度。它具有重载运算符,包括“+=”、“-=”、“*=”和“/=”。每个重载运算符都设计为将一些双精度类型的输入加、减、乘或除到角度 class 所持有的度值。 Angle class 包装器以与上例中描述的完全相同的方式映射这些重载运算符。当我测试 Python 中的加法、减法和乘法运算符时,它们运行得非常好。除法运算符,不是这样。当我 运行 像这样的简单测试时:
A = Angle(1) # instantiate Angle object with magnitude of 1 radian
A /= 2.0 # attempt to divide the radian measurement by 2
我收到以下错误:
TypeError: unsupported operand type(s) for /=: 'Angle' and 'float'
基于这个问题:
Error when trying to overload an operator "/"
我看到 Python3(我正在使用的版本)有一种独特的理解“/”字符的方式。但是,此解决方案对我不起作用,因为我使用的 class 是包装的 C++ class.
我的问题:有没有办法使用 boost 以保留相同语法的方式将重载运算符“/=”从 C++ 映射到 python(即不在 C++ 中编写名为执行相同操作但必须用“Angle.selfdiv()”) 调用的“selfdiv”?也许有一些方法可以覆盖 Python 解释正斜杠字符的方式?
Python 3 更改了除法运算符的定义方式,Boost.Python 的自动生成版本使用旧的 Python 2 样式进行就地除法,没有更长的作品。这似乎是一个疏忽,因为非就地版本已更新为 Python 3 的 __truediv__
魔术方法。关于这件事有一个open GitHub issue。在它得到修复之前,您可以像定义任何其他 class 成员函数一样定义 __itruediv__
and/or __ifloordiv__
:
class_<Foo>("Foo")
.def(
"__itruediv__",
&Foo::operator/=,
return_self<>{}
);