将 python class 翻译成 cython

Translating python class into cython

我在Python中有以下代码:

class DisjointSet:
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [0 for x in range(n)]

    def find(self, v):
        if v != self.parent[v]:
            self.parent[v] = self.find(self.parent[v])
        return self.parent[v]

其余代码与'code complexity'类似,此处不再赘述。

所以我想把上面的代码翻译成cython代码(我知道一点C++,我设法把我所有的代码翻译成C++,但我想试试cython,看看它与c++和python).我有类似的东西:

disjointset.pyx:

# distutils: language=c++
from libcpp.vector cimport vector

cdef class DisjointSet:
    cpdef public vector[int] parent, rank

    def __init__(self, int n):
        for i in range(n):
            self.parent.push_back(i)
            self.rank.push_back(0)

    def find(self, int v):
        if v != self.parent[v]:
            self.parent[v] = self.find(self.parent[v])
        return self.parent[v]

setup.py:

from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("cPercolation.pyx", annotate=True)
)

而我运行python setup.py build_ext --inplace在Windowspowershell中编译代码。但是,当我导入代码并在 Python 中尝试时,它有时会报错(process doesn't return 0),有时在我调用 find 方法时会报 RecursionError。那么翻译上述代码的正确方法是什么?我已经阅读了官方文档,但我仍然不确定 cdefcpdef.

之类的内容

编辑:我已经添加了 for 循环来解决问题,但我应该如何改进 cython 代码?当我查看生成的 html 文件时,仍然有很多黄色突出显示(python 交互)。具体来说,我想问一下我应该如何使用 cdefcpdef 来使 class 方法(DisjointSet.find)更像 C++ 代码。

C++ vector operator [] does not check bounds, out of bound access 给出了一个随机值,导致后续vector访问的segment fault,你会注意到一个非零的exit code .

相反,使用 .at()which has bounds checking,cython 会将 std::out_of_range 异常转换为 IndexError:

 def find(self, int v):
     try:
         pv = self.parent.at(v)
     except IndexError:
         return None
     ...