python - 在 C++ 中使用 Python 对象

标签 python c++ object cython

我正在编写一个代码,使用区间分析的方法计算非线性映射的图像,应用 minkowski 和并重复任意次数的迭代。

我已经用 Python 编写了一个工作代码,但是我希望能够用 C++ 实现算法的一些迭代/递归密集型部分,以便从提高的速度中获益。我过去使用过 Cython 并取得了很好的效果,但我想练习我的 C++。

此外,我的对象非常复杂,我宁愿避免用 C++ 实现它们(婴儿步骤!)。

所以我的问题是:

1) 在 C++ 中使用 Python 对象是否会阻碍效率的提高?

2) 如果不是,是否可以使用 Cython 包装一个 C++ 函数,该函数迭代/递归 python 对象?

更具体地说,我有一个递归算法,它在 BST 的左右子节点上递归(尽管它是一个经过相当大修改的 BST,所以我不想纠结于用 C++ 实现它的细节) ,但是运行时间非常高,所以我想用 C++ 编写它。

最佳答案

是的。您将获得比纯 python 更高的速度,但无法与使用纯 C/C++ 时获得的提升相提并论。如果你想处理 Python 对象,你需要通过 Python C/API 来完成。 ;这增加了执行的开销,这是您必须为允许与 Python 交互而付出的代价。

请注意,这涉及很多复杂性,因为您需要熟悉 API 并阅读函数对对象引用的作用、如何创建列表、打包元组等。如果您只是创建几个 public Cython cdef 函数来包装对象上的方法,则可以跳过所有这些。这会生成为您处理这些问题的所有 CPython 代码。

一个包装和嵌入愚蠢对象的小例子可能看起来像这样(注意,我正在使用 .c 为此,c++ 有类似的步骤) :

class PyClass(object):

    def __init__(self):
        self.data = []

    def add(self, val):
        self.data.append(val)

    def __str__(self):
        return "Data: " + str(self.data)

cdef public object createPyClass():
    return PyClass()

cdef public void addData(object p, int val):
    p.add(val)

cdef public char* printCls(object p):
    return bytes(str(p), encoding = 'utf-8')

cython pycls.pyx编译(使用--cplus for c++)会生成一个.c.h 文件分别包含源代码和函数声明。您现在需要做的就是创建一个启动 Python 的 main.c 文件,然后您就可以调用这些函数了:

#include "Python.h"   // Python.h always gets included first.
#include "pycls.h"    // Include your header file.

int main(int argc, char *argv[])
{
    Py_Initialize();   // initialize Python
    PyInit_pycls();    // initialize module (initpycls(); in Py2)
    PyObject *obj = createPyClass();
    for(int i=0; i<10; i++){
        addData(obj, i);
    }
    printf("%s\n", printCls(obj));
    Py_Finalize();
    return 0;
}

用适当的标志编译它(你可以从 python-config [Py2] 的 python3.5-config 获得):

gcc pycls.c main.c -L$(python3.5-config --cflags) -I$(python3.5-config --ldflags) -std=c99

将创建与您的对象交互的可执行文件:

./a.out
Data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

所有这些都是通过使用 Cython 以及生成 .h 头文件的 public 关键字来完成的。您也可以只使用 Cython 编译一个 python 模块,然后自己创建 header /处理额外的样板文件。因为我认为您不想被 C-API 学习所困扰,所以这不应该是正确的方法。

正如@freakish 在他的评论中所述,提取数据 ( numpy has a C-API you can use for this ) 并在纯 C++ 中处理它是理想的选择。通常,如果您在 C/C++ 中运行循环并在那里执行繁重的工作,您将获得很好的加速。

关于python - 在 C++ 中使用 Python 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37577676/

相关文章:

python - downloadPage 回调函数的问题

python - 为什么 random() * random() 与 random() ** 2 不同?

python - Tensorflow:如何保存经过训练的模型的差异

c++ - 在 C++11 中替换元组中的类型

C++ 从磁盘读取文件并将其写入共享内存

c++ - 我将如何着手为 Windows 构建 Node 嵌合体?

c++ - Arduino 库中的全局对象

Python re regex 子字母不包含在引号中,并且如果它们匹配特定单词(包括正则表达式组/匹配)则不包含在引号中

javascript - 在 setTimeout 中使用对象字面量函数

python - 奇怪的 Python OOP 函数调用错误