如何使用Boost.Python定义Python元类?

Pau*_*nta 14 c++ python metaclass boost-python python-3.x

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

如果有一个Boost.Python解决方案,这将是理想的.如果没有,使用Python C API(或Boost和C API的组合)的解决方案也是好的.由于我的其他课程都有Boost,所以我宁愿将SWIG作为最后的手段.

注意:这实际上是我正在尝试解决的一个更大问题的一部分,如果您感兴趣,我已经在使用Boost.Python设置包装类的元类时询问过.

bab*_*bak 4

好吧,这感觉像是黑客,但似乎有效。

#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__");
}
Run Code Online (Sandbox Code Playgroud)

然后在Python中

from meta import Meta

class Test(object):
    __metaclass__ = Meta

print Test, Test.foo
<class '__main__.Test'> bar
Run Code Online (Sandbox Code Playgroud)

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

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

return type.attr("__new__")(type, name, bases, attrs);
Run Code Online (Sandbox Code Playgroud)

return type.attr("__new__")(cls.attr("__class__"), name, bases, attrs);
Run Code Online (Sandbox Code Playgroud)

或类似的东西,因此使用 Boost::Python::class 而不是类型。