如何让pybind11的stubgen将std::vector生成为Sequence[T]类型?
解决方案
方案一:为单个绑定显式指定类型注解
在pybind11的绑定代码中,通过py::arg的annotation方法直接指定参数的Python类型提示,stubgen会读取该注解生成对应的Sequence[T]类型。
修改后的C++绑定代码示例:
py::class_<Dummy>(m, "Dummy") .def(py::init<const std::vector<std::string>&>(), py::arg("names").annotation("Sequence[str]"));
生成的存根会变为:
class Dummy: def __init__(self, names: Sequence[str]) -> None: ...
方案二:全局修改std::vector的类型注解(批量场景)
如果项目中有大量std::vector<T>类型的绑定需要统一改为Sequence[T],可以通过自定义pybind11的类型转换器注解实现全局生效,无需逐个修改绑定代码。
在绑定代码的全局位置添加以下模板特化:
#include <pybind11/stl.h> namespace pybind11 { namespace detail { template <typename T> struct type_caster<const std::vector<T>&> : public type_caster_base<const std::vector<T>&> { static constexpr auto name = _("Sequence[") + make_caster<T>::name + _("]"); }; } // namespace detail } // namespace pybind11
这样所有绑定了const std::vector<T>&的参数,stubgen都会自动生成Sequence[T]的类型签名。
补充方案:调整参数处理逻辑
如果愿意修改C++函数的参数绑定逻辑,也可以用py::sequence作为绑定参数类型,再在绑定逻辑中转换为std::vector<T>,结合显式注解达到效果:
py::class_<Dummy>(m, "Dummy") .def(py::init([](py::sequence names) { std::vector<std::string> name_vec; py::cast_into(names, name_vec); return Dummy(name_vec); }), py::arg("names").annotation("Sequence[str]"));
内容的提问来源于stack exchange,提问作者Martin Prazak
相关产品推荐
相关产品推荐

