从Python中提取类

0 投票
1 回答
1567 浏览
提问于 2025-04-16 14:12

我正在用C++写一个游戏,使用boost.python库作为脚本系统。

我有一个抽象类叫做Object。现在我创建了一个新类,从Object继承,并在某个地方写了Object *obj = new SomeCoolObject();

我还有一个对象的映射表:map<string, Object*> objects。所以在创建对象后,我执行:objects.insert("name", obj);

别提释放内存的事,我把那部分隐藏起来了,以减少代码(我在使用智能指针)。

所以问题是:

我想要一个文件夹,里面有一些Python文件。在每个文件中,我描述一些从Object派生的类,比如:

class SomeCoolObject(Object):
   ...

我该如何将这个类绑定到C++中?换句话说,如何告诉C++程序有这样一个新类。

再说一次:可能会有几个Python文件包含这样的类,我需要导出所有这些类。

有什么想法吗,大家?

1 个回答

1

如果你已经加载了这个模块(比如用 boost::python::import("module_name")),那么你就可以通过 attr() 这个成员函数来引用里面的任何类。通常我会在它周围写一个包装函数,因为如果这个类(或者其他任何属性)不存在,它可能会抛出一个异常。举个例子:

boost::python::object getattr(const boost::python::object &obj, const std::string &name)
{
    try
    {
        return obj.attr(boost::python::str::str(name));

    }
    catch(const boost::python::error_already_set &err)
    {
        /* we need to fetch the error indicators *before*
         * importing anything, as apparently importing
         * using boost python clears the error flags.
         */

        PyObject *e, *v, *t;
        PyErr_Fetch(&e, &v, &t);

        boost::python::object AttributeError = boost::python::import("exceptions").attr("AttributeError");

        /* Squash the exception only if it's an AttributeError, otherwise
         * let the exception propagate.
         */
        if (PyErr_GivenExceptionMatches(AttributeError.ptr(), e))
            return boost::python::object(); // None

        else
            throw;
    }
}

[... later in the code ...]

using namespace boost::python;

object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");


object your_module = import("module_name");
object your_class = getattr(main_namespace, "SomeCoolObject");

// Now we can test if the class existed in the file
if (!your_class.is_none())
{
     // it exists! Have fun.
}

撰写回答