Skip to main content
 首页 » 编程设计

python之将 python 类翻译成 cython

2025年05月04日20jillzhang

我在 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] 

其余代码在“代码复杂度”方面类似,此处不再赘述。

所以我想把上面的代码翻译成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] 

设置.py:

from distutils.core import setup 
from Cython.Build import cythonize 
 
setup( 
    ext_modules = cythonize("cPercolation.pyx", annotate=True) 
) 

然后我在 Windows powershell 中运行 python setup.py build_ext --inplace 来编译代码。但是,当我导入代码并在 Python 中尝试时,有时会出现错误(进程不返回 0),有时会在我调用 find 方法时出现 RecursionError。那么翻译上述代码的正确方法是什么?我已经阅读了官方文档,但对于cdef、cpdef之类的内容,我仍然不确定。

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

请您参考如下方法:

C++ vector 运算符[] does not check bounds ,越界访问给出了一个随机值,这会导致后续向量访问中出现段错误,您会注意到一个非零退出代码。

相反,使用.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 
     ...