【问题标题】:How to define a Python metaclass with Boost.Python?如何使用 Boost.Python 定义 Python 元类?
【发布时间】:2012-02-21 11:40:31
【问题描述】:

Python C API 有PyObject *PyType_Type 对象,相当于解释器中的type。如果我想在 C++ 中定义一个元类,我如何将type 设置为它在 Boost.Python 中的基础之一?另外,在 C++ 中定义 Python 元类时我还应该考虑哪些其他事项?

如果有 Boost.Python 解决方案,那就太理想了。如果没有,使用 Python C API(或 Boost 和 C API 的组合)的解决方案也很好。由于我的其他类都暴露在 Boost 中,所以我宁愿将 SWIG 作为最后的手段。

注意:这实际上是我试图解决的一个更大问题的一部分,如果你有兴趣,我已经在Setting metaclass of wrapped class with Boost.Python 中询问过这个问题。

【问题讨论】:

  • 您只是在寻找 Boost.Python 解决方案吗?我想我可以用 SWIG 解决这个问题 :)
  • @awoodland Boost.Python 更可取,但我不反对 SWIG。
  • 好的,如果你没有得到一个好的 Boost.Python 答案,请 ping 我,用另一个 @ 提醒我,我会看看用 SWIG 做的。
  • 我不确定这是否可能仅使用 c++ 作为 boost python 已经将公开类型的元类设置为 Boost::Python::class。您也许可以在 c++ 中编写一个具有 new 方法的类,然后将其用作 python 中的元类。
  • @babak 这已经足够了™,但暴露的元类仍然必须继承自 Python 的 type 的等效项。

标签: c++ python python-3.x boost-python metaclass


【解决方案1】:

好吧,这感觉像是一个 hack,但它似乎有效。

#include <boost/python.hpp>

class Meta
{
public:
    static boost::python::object
    newClass(boost::python::object cls, std::string name, boost::python::tuple bases, boost::python::dict attrs)
    {
        attrs["foo"] = "bar";
        boost::python::object types = boost::python::import("types");
        boost::python::object type = types.attr("TypeType");
        return type.attr("__new__")(type, name, bases, attrs);
    }
};

BOOST_PYTHON_MODULE(meta)
{
    boost::python::class_<Meta>("Meta")
    .def("__new__", &Meta::newClass)
    .staticmethod("__new__");
}

然后在python中

from meta import Meta

class Test(object):
    __metaclass__ = Meta

print Test, Test.foo
<class '__main__.Test'> bar

我尝试了其他一些没有使用 boost::python::object 系统的东西,但无法从 python 端得到任何像这样工作的东西。

虽然严格来说这不是一个元类,因为它不继承自 type,但它的行为就像一个元类,因为 type 在调用 new 时直接在 newClass 函数中使用。如果这不是问题,那么从

更改它可能是明智的
return type.attr("__new__")(type, name, bases, attrs);

return type.attr("__new__")(cls.attr("__class__"), name, bases, attrs);

或类似的东西,所以使用 Boost::Python::class 代替 type。

【讨论】:

  • 我试试看。它很可能不适用于 Python 3(这是我想使用的版本),但我想如果必须的话我会降级。
  • 如果您还没有这样做,可能值得在 boost.2283326.n4.nabble.com/Python-c-sig-f2696818.html 上提问
  • 我给你赏金是因为这个答案很好,但我还不会接受。我仍在寻找适用于 Python 3 的解决方案。如果我没有找到任何我会接受这个答案。
猜你喜欢
  • 2012-03-26
  • 2023-03-02
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2014-07-10
  • 2014-02-28
  • 1970-01-01
相关资源
最近更新 更多