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设置包装类的元类时询问过.
好吧,这感觉像是黑客,但似乎有效。
#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 而不是类型。
| 归档时间: |
|
| 查看次数: |
1202 次 |
| 最近记录: |