【问题标题】:Boost-Python: Expose a class to Python which is a subclass of a Python class (str)Boost-Python:向 Python 公开一个类,它是 Python 类 (str) 的子类
【发布时间】:2022-08-16 06:13:38
【问题描述】:

我试图让 Boost Python 函数返回一个 Python 对象,它是 Python 内置类的子类(此处为 str):

我的第一种方法是在 Python 模块mystr.py 中创建类:

class MyStr(str):
    def __truediv__(self, other):
        return self + other

然后我使用 Boost 导入该模块,然后返回该类型的 python 对象,我在 C++ 中沿这些行使用 somehting,导入模块并调用py::exec

py::object AsMyStr(std::string const &s)
{
    py::object my_str = py::import(\"mystr\");
    py::dict my_namespace(my_str.attr(\"__dict__\"));
    
    my_namespace[\"_MYSTR_test\"] = s;
    py::exec(
        \"_MYSTR_test = MyStr(_MYSTR_test)\\n\",
        my_namespace, my_namespace);
    return my_namespace[\"_MYSTR_test\"];
}

在 Boost-Python 模块中公开这个函数,这在 Python 端正确地给了我一个 MyStr 实例,可以相应地使用它:

 a = AsMyStr(\"Hello\")
 b = \" World\"
 print(a / b)
 # \"Hello World\"

我只是想知道 str 的子类化是否可以在 C++ 中的 Boost-Python 方面完成。在这种情况下,我无法让__truediv__ 工作:

class MyStr : public py::str
{
public:
    MyStr(py::object const &o) : py::str(o)

    MyStr __truediv__(other)
    {
         return MyStr(*this + other);
    }
 }

将其作为模块公开

 BOOST_PYTHON_MODULE(MyStr)
 {
     py::class_<MyStr, py::bases<py::str>>(\"MyStr\", py::no_init)
         .def(py::init<py::object const &>())
         .def(\"__truediv__\", &MyStr::__truediv__)
         ;
 }

但是在 Python 端使用这个类会导致:

 a = MyStr(\"Hello\")
 b = \" World\"
 print(a / b)
 # ValueError: character U+5555eaa0 is not in range [U+0000; U+10ffff]

如何在 C++ 实现中定义和公开类 MyStr 以在 Python 端返回一个“true” MyStr,它是 str 的子类?


我将代码上传到https://gitlab.com/kohlrabi/learn-boost-pythonmaster 分支包含第一个解决方案,cpp_class 分支包含第二个非工作解决方案。

    标签: python c++ boost boost-python


    【解决方案1】:

    U+0000 到 U+10fffff 的范围表示all possible Unicode code points

    您的字符串很可能在 C++ 和 Python 之间进行编码,因此您可以尝试使用 .decode('cp1252') 中的编码。或者您可以执行.decode('utf-8', 'surrogatepass'),坏字符将在结果字符串中显示为未解码的字节。

    surrogatepass 更改为replace,它们会变成问号并更改为忽略,然后它们就会消失。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 2020-09-03
    • 2022-07-03
    • 2013-08-04
    • 1970-01-01
    相关资源
    最近更新 更多