Boost.Python 列出所有暴露的类和属性

Posted

技术标签:

【中文标题】Boost.Python 列出所有暴露的类和属性【英文标题】:Boost.Python list all exposed classes and attributes 【发布时间】:2018-09-03 13:06:09 【问题描述】:

我正在使用 Boost.Python 将类从 C++ 公开到 Python,例如:

class_<Point>("Point").
        def(init<double, double, double>()).
        add_property("X", &Point::GetX, &Point::SetX).
        add_property("Y", &Point::GetY, &Point::SetY).
        add_property("Z", &Point::GetZ, &Point::SetZ).
        def("SetXYZ", &Point::SetPnt);

我还将一些变量公开为我的主模块的属性:

MainModule.attr("Window") = object(ptr(mainWindow));

是否可以列出所有公开的类和/或模块的所有属性(在 C++ 中)?

我希望获得所有公开类的列表 (vector&lt;string&gt;):在本例中只是“Point”。暴露的变量也是如此,在这种情况下只是“窗口”。

【问题讨论】:

我看不出这是怎么重复的 对不起,我误解了你的问题,你所说的 C++ 模块是什么意思? 它不是 C++ 模块,而是这样制作的模块对象:object MainModule = import("___main___"); 【参考方案1】:

使用 Python 反射功能:

从 C++ 执行一些代码:

PyRun_SimpleString("import inspect");
PyRun_SimpleString("import MyModule");
string getClassesCode =
    "def GetClasses():\n"
    "    for name, obj in inspect.getmembers(MyModule):\n"
    "        if inspect.isclass(obj):\n"
    "            yield obj.__name__\n"
    "_classes = list(GetClasses())\n";


    typedef boost::python::list pylist;
    object main_namespace = MainModule.attr("__dict__");

    try
    
        exec(getClassesCode.c_str(), main_namespace);
    
    catch (error_already_set  const &)
    
        PyErr_Print();
    

    pylist _classes = extract<pylist>(main_namespace["_classes"]);

    for (int i = 0; i < len(_classes); ++i)
    
        string className = extract<string>(_classes[i]);
        //do whatever you need with the class name
    

【讨论】:

我想我可能误会了你……你不是说你想在你的 python 代码中使用 C++ 代码吗?这个 sn-p 似乎您正在做相反的事情,即将一些 python 类导入您的 C++ 代码?我认为让我失望的是“暴露类从 C++ 到 Python”部分...... @SkepticalEmpiricist 是的,但这无关紧要,我只是使用 Python 的自省功能来获取所有类,然后将该信息发送到 C++。从 C++ 到 Python 的类讲解之前已经做过了,这里就不贴了(因为篇幅太长,因为不相关) 仍然觉得我并不完全支持你——你是说从 C++ 到 Python 的阐述是无关紧要的,但我再次认为最初的问题是确切地关于如何要做到这一点。因此,我的建议显然是对这个特定要求的解决方案......【参考方案2】:

是否可以列出所有公开的类和/或所有属性 模块(在 C++ 中)?我希望获得所有公开类的列表 (vector&lt;string&gt;) ...

我不知道 Boost.Python 有这样一个特性,但是一个替代方案,虽然会带来开销,但可能是公开一个列表(你可以拥有它std::vector&lt;string&gt;,为什么不呢?)你准备“手动" 在 C++ 方面并在您更改曝光组合时保持它。这样,您只需要知道这样的列表或列表的名称并最初导入它们即可获得这样的功能。

【讨论】:

你建议手动做,这不是我需要的 @Sturm 完全同意你的看法,这是一个手动解决方案,我从来没有说过。相反,我的意思是在没有内置替代方案的情况下,它可能会达到您的目的。在这里是为了实用,因为这个解决方案需要最少的时间来实施和维护。我错了吗? 我能想到很多情况并非如此。想象一下我的应用程序的第三方插件开发人员想要将他的对象暴露给这个 python 脚本引擎并拥有主应用程序所具有的所有功能(在这种情况下是可用的类,但不限于此,实际目的是提取方法签名到帮助用户编写python代码)。无论如何,这基本上是将我所有的展示代码复制到 a) 暴露给 python b) 添加到字符串列表 @Sturm 好的,我直截了当地说,在给定的场景中,您希望第 3 方开发人员将其暴露的实体作为原始单数列表的一部分,以便 python代码可以保持不变,不必知道更多列表的名称并导入它们,对吧? @Sturm 好的,我想我支持你:) 问题:你觉得让插件让主模块知道它们所有暴露的对象有问题吗?

以上是关于Boost.Python 列出所有暴露的类和属性的主要内容,如果未能解决你的问题,请参考以下文章

Boost.Python - 暴露一个类

Boost Python 暴露 C++ 类,构造函数采用 std::list

boost::python:如何覆盖静态属性?

Boost不将模块暴露给python

在 boost python 中暴露 C++ 接口

使用 boost::python 从 c++ 函数访问大表