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

如何从py::module对象访问已绑定的py::class类?

问题

在使用pybind11暴露C++代码时,能否从py::module对象访问已定义的py::class类?已知可以从绑定类直接使用attr,但想知道能否通过模块实现同样操作。

具体场景是实现MyOtherClass的__repr__方法时,调用已为MyClass定义的__repr__,现有代码如下:

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/operators.h>


class MyClass {
 public:
    MyClass() = default;
    // ...
};

class MyOtherClass {
 public:
    MyOtherClass() = default;
    // ...
    MyClass val;
};

// -------------------------------------------------------------------------

template < typename T >
py::class_< T > bind(py::module& module, const char* name);


template < >
py::class_< MyClass > bind(py::module& module, const char* name) {
    return py::class_< MyClass >(module, name)
        .def(py::init< >(), "Constructs a new instance")
        // ...
        .def("__repr__", [](const MyClass& obj) { return "something"; });
}

template < >
py::class_< MyOtherClass > bind(py::module& module, const char* name) {
    return py::class_< MyOtherClass >(module, name)
        .def(py::init< >(), "Constructs a new instance")
        // ...
        .def("__repr__", [](const MyOtherClass& obj) { return module.class("MyClass").attr("__repr__")(obj.val); });   //  <- 如何调用为MyClass定义的__repr__方法?
}

// -------------------------------------------------------------------------

PYBIND11_MODULE(pymodule, module) {
    // ...
    bind< MyClass >(module, "MyClass");
    bind< MyOtherClass >(module, "MyOtherClass");
    // ...

}
解决方案

有两种可行方式实现MyOtherClass调用MyClass的__repr__方法:

方法1:通过模块获取已绑定的类并调用方法

利用py::module的attr()方法直接获取模块中已绑定的MyClass,再取出其__repr__方法调用。需要将C++的MyClass实例转为pybind11对象,用py::cast()完成转换:

template < >
py::class_< MyOtherClass > bind(py::module& module, const char* name) {
    return py::class_< MyOtherClass >(module, name)
        .def(py::init< >(), "Constructs a new instance")
        .def("__repr__", [&module](const MyOtherClass& obj) {
            auto my_class_repr = module.attr("MyClass").attr("__repr__");
            return my_class_repr(py::cast(obj.val));
        });
}

注意:必须保证MyClass的绑定(即bind<MyClass>调用)在MyOtherClass之前执行,否则模块中找不到MyClass的定义。

方法2:直接复用C++层面的实现

如果不需要走Python方法调用流程,直接把MyClass的__repr__逻辑抽成独立函数,在MyOtherClass中直接调用,这种方式效率更高:

// 抽离MyClass的__repr__实现为独立函数
std::string my_class_repr(const MyClass& obj) {
    return "something";
}

template < >
py::class_< MyClass > bind(py::module& module, const char* name) {
    return py::class_< MyClass >(module, name)
        .def(py::init< >(), "Constructs a new instance")
        .def("__repr__", &my_class_repr);
}

template < >
py::class_< MyOtherClass > bind(py::module& module, const char* name) {
    return py::class_< MyOtherClass >(module, name)
        .def(py::init< >(), "Constructs a new instance")
        .def("__repr__", [](const MyOtherClass& obj) {
            return my_class_repr(obj.val);
        });
}

内容的提问来源于stack exchange,提问作者joaocandre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 21:24:59