提升python typedef

时间:2018-12-05 16:58:29

标签: python c++ boost-python

我正在尝试使用boost python将带有名称别名的C ++类公开给python。

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也可以。但是我需要将定义保留在同一模块中。有没有更好的方法可以做到这一点?

2 个答案:

答案 0 :(得分:2)

由于typedef仅引入了别名,因此您的代码仅以不同的名称注册了相同的类。

建议:

  • 您为什么仍要这么做?只需以其真实名称注册一次即可。如您所述,在Python中创建别名(同样,为什么?)很容易。
  • 如果您只是声明一个基类并从中派生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)
  ;
}

答案 1 :(得分:2)

我会采用Ulrich提到的“等同于Python Bar = Foo的C ++”方法。

您可以使用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");
}