C++ Python 导入类;调用方法

Posted

技术标签:

【中文标题】C++ Python 导入类;调用方法【英文标题】:C++ Python import class; call methods 【发布时间】:2013-05-14 14:02:33 【问题描述】:

我正在使用 Python 2.7。我不清楚如何将 Python 嵌入到 C++ 中,如下所示:http://docs.python.org/2.7/extending/embedding.html

我在一个名为 test.py 的文件中有一个简单的 python 示例:

class math:
    #def __init__(self):
    def add(self, num1, num2):
        return num1 + num2

    def subtract(self, num1, num2):
        return num1 - num2

从 python,我会做这样的事情:

>>> from test import math
>>> m = math()
>>> a = m.add(1, 2)
>>> s = m.subtract(1, 2)

我有一些 C++ 代码的开头来做到这一点:

PyObject *pName, *pModule;
Py_Initialize();
pName = PyString_FromString("test");
pModule = PyImport_Import(pName);

这似乎工作得很好。但是,这似乎相当于在 Python 中执行此操作:

import test

如何导入 Python 类数学?

谢谢

【问题讨论】:

【参考方案1】:

这是 C 语言中的一个快速的 n'dirty 示例,它相当于...

>>> import mymath
>>> m = mymath.math()
>>> print '1 + 2 = %d' % m.add(1, 2)

请注意,我已将模块从 test 重命名为 mymath,因为标准 Python 库中有一个名为 test 的模块。

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <python2.7/Python.h>

int main()

    setenv("PYTHONPATH", ".", 1);

    Py_Initialize();

    PyObject* module = PyImport_ImportModule("mymath");
    assert(module != NULL);

    PyObject* klass = PyObject_GetAttrString(module, "math");
    assert(klass != NULL);

    PyObject* instance = PyInstance_New(klass, NULL, NULL);
    assert(instance != NULL);

    PyObject* result = PyObject_CallMethod(instance, "add", "(ii)", 1, 2);
    assert(result != NULL);

    printf("1 + 2 = %ld\n", PyInt_AsLong(result));

    Py_Finalize();

    return 0;

...输出...

$ gcc foo.c -lpython2.7 && ./a.out
1 + 2 = 3

但是,如果您在 Py_InitializePy_Finalize 之间使用 Python/C API 进行大量工作,则必须注意引用计数,并在适当的时候使用 Py_INCREFPy_DECREF

【讨论】:

谢谢。完全按预期工作。我唯一不同的是不包括 setenv() 调用。这似乎在 MSVS 2008 c++ 中不可用,或者,我不知道在哪里可以找到它。没有它,测试运行良好。 @DooDah 听起来你的模块已经在PYTHONPATH 中了。我在没有 setenv 行的情况下从 Ubuntu 上的当前工作目录导入时遇到问题。【参考方案2】:

您不能导入类,但可以导入文件或库(大多数语言都是如此?)——这正是您在 test.py 中所做的。

【讨论】:

问题是如何将 python 类导入 C++。标记为正确的答案就是解决方案。

以上是关于C++ Python 导入类;调用方法的主要内容,如果未能解决你的问题,请参考以下文章

使用 SWIG 包装对象从 C++ 调用 Python 函数的最简洁方法是啥

为啥Python调用方法,有的前面加类名,有的不加?

带有类方法的 Cython 回调

python 类方法和静态方法的区别

Python的实例方法,类方法,静态方法之间的区别及调用关系

python 动态调用模块类方法(django项目)