You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Boost-Python中用C++实现继承str的Python类并支持__truediv__

问题描述

希望通过Boost-Python让C函数返回继承自Python内置str类的对象,已实现「Python端定义子类+ C调用实例化」的可行方案,但直接在C中定义继承py::str的类时,__truediv__方法无法正常工作,报错ValueError: character U+5555eaa0 is not in range [U+0000; U+10ffff],需解决纯C端的正确实现方式。


可行的Python类+ C++调用方案

Python模块定义(mystr.py)

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

C++调用实现

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"];
}

Python调用验证

a = AsMyStr("Hello")
b = " World"
print(a / b)
# 输出:Hello World

有问题的纯C++实现方案

C++类定义

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

    MyStr __truediv__(py::object 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++实现方案

问题根源:Python内置不可变类型(如str)的对象模型特殊,直接在C++中继承py::str会破坏内存管理逻辑,导致非法内存访问。以下是两种可靠实现方式:

方式1:通过Boost-Python包装Python原生str子类

#include <boost/python.hpp>
namespace py = boost::python;

struct MyStrOps {
    static py::object truediv(py::self self, py::object other) {
        // 拼接字符串后,用当前类实例化新对象返回
        py::object str_result = py::str(self) + py::str(other);
        return py::type(self)(str_result);
    }
};

BOOST_PYTHON_MODULE(MyStr) {
    // 获取Python原生str类型作为父类
    py::object str_type = py::import("__builtin__").attr("str");
    // 定义MyStr类并绑定方法
    py::class_<py::object, boost::noncopyable>("MyStr", str_type, py::init<py::object>())
        .def("__truediv__", &MyStrOps::truediv)
        ;
}

方式2:用类型转换器关联C++对象与Python str子类

#include <boost/python.hpp>
namespace py = boost::python;

// C++端数据存储类
class MyStr {
public:
    MyStr(const std::string& s) : content_(s) {}
    std::string content_;
};

// 自定义类型转换器:将C++ MyStr转为Python的MyStr实例
struct MyStrToPython {
    static PyObject* convert(const MyStr& ms) {
        // 获取Python端定义的MyStr类(需确保mystr模块可导入)
        py::object my_str_cls = py::import("mystr").attr("MyStr");
        return py::incref(my_str_cls(ms.content_).ptr());
    }
};

BOOST_PYTHON_MODULE(MyStr) {
    // 注册类型转换器
    py::to_python_converter<MyStr, MyStrToPython>();
    
    // 暴露C++类及方法
    py::class_<MyStr>("MyStr", py::init<const std::string&>())
        .def("__truediv__", [](const MyStr& self, const std::string& other) {
            return MyStr(self.content_ + other);
        })
        ;
}

内容的提问来源于stack exchange,提问作者Jan Christoph Terasa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 06:21:57