提升 python typedef

Boost python typedef

我正在尝试使用 boost python 公开名称别名为 python 的 C++ class。

struct Foo
{
  void hi() const { std::cout << "hi" << std::endl; }
};

BOOST_PYTHON_MODULE(Example)
{
  typedef Foo Bar;

  class_<Foo>("Foo")
    .def("hi", &Foo::hi)
  ;

  class_<Bar>("Bar")
    .def("hi", &Bar::hi)
  ;
}

除了烦人的 RuntimeWarning 之外,代码按预期工作。

RuntimeWarning: to-Python converter for Foo already registered; second conversion method ignore

在 python 中添加 Bar = Foo 也可以。但我需要将定义保留在同一个模块中。有没有更好的方法来实现这个?

由于typedef只引入了一个别名,你的代码只是在不同的名字下注册相同的class。

建议:

  • 你为什么想要那个?只需以真实姓名注册一次即可。正如您提到的,在 Python 中创建别名(同样,为什么?)很容易。
  • 如果您只是声明了一个基class 并从中派生了 FooBar,您将拥有不同的类型并且警告也会消失。
  • 您可能还可以编写等同于 Python Bar = Foo 的 C++,即将对象简单分配给模块命名空间中的名称。

鉴于下面的反馈要求支持遗留代码,我会这样做:

// same as above
struct Foo { ... };

// For legacy reasons, it is mandatory that Foo is exported
// under two names. In order to introduce new C++ types, we
// just derive from the original Foo. The approach using a
// typedef doesn't work because it only creates an alias but
// not an existing type.
struct FooType: Foo {};
struct BarType: Foo {};

BOOST_PYTHON_MODULE(Example)
{
  class_<FooType>("Foo")
    .def("hi", &FooType::hi)
  ;
  class_<BarType>("Bar")
    .def("hi", &BarType::hi)
  ;
}

我会采用 Ulrich 提到的 "C++ equivalent to the Python Bar = Foo" 方法。

您可以使用 boost::python::scope 访问当前模块及其属性。

#include <boost/python.hpp>
#include <iostream>

namespace bp = boost::python;

struct Foo
{
    void hi() const { std::cout << "hi" << std::endl; }
};

BOOST_PYTHON_MODULE(Example)
{
    bp::class_<Foo>("Foo")
        .def("hi", &Foo::hi)
        ;

    bp::scope().attr("Bar") = bp::scope().attr("Foo");
}