如何使用 Boost.Python 定义 Python 元类?
Posted
技术标签:
【中文标题】如何使用 Boost.Python 定义 Python 元类?【英文标题】:How to define a Python metaclass with Boost.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
的等效项。
【参考方案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 的解决方案。如果我没有找到任何我会接受这个答案。以上是关于如何使用 Boost.Python 定义 Python 元类?的主要内容,如果未能解决你的问题,请参考以下文章
通过 Boost Python 将 Python 函数转换为 C++,用作回调