cython的扩展类型的共享声明,它是另一个扩展类型的成员数据

2024-05-13 14:19:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使用share of declaration for extension types共享一个类的声明,这个类是cython中另一个类的成员数据。你知道吗

代码示例:

这是由用户运行的python包装器(run.py)。它声明了一个Solver类。你知道吗

#! /usr/bin/env python
# filename: run.py 

import Solver

S = Solver.Solver()
Result = S.Solve()

Solver对象有一个cpdef Solve()成员函数,该函数从代码的python部分调用一次。Solver类具有cdef object Computation成员数据:

# filename: Solver.pyx

from Computation cimport Computation
cdef class Solver:
    cdef object Comp

    def __cinit__(self):
        self.Comp = Computation()

    cpdef double Solve(self):
        Result =  self.Comp.Add(4)
        return Result

Computation类只是一个cython代码:

# filename: Computation.pxd

cdef class Computation:
    cdef int a
    cdef double Add(self,double b)

以及

# filename: Computation.pyx

cdef class Computation:
    def __cinit__(self):
        self.a = 3

    cdef double Add(self,double b):
        return self.a + b

setup.py是:

# filename: setup.py

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

setup(
        package_data = {"Computation": ["Computation.pxd"]},
        ext_modules = cythonize(["*.pyx"],include_path=["."]),
)

Solver.Solve()多次调用Computation.Add(),但为了简单起见,这里我抑制了for循环。关键是调用Add()的代价应该最小,因此我用cdef声明了它。你知道吗

问题:

所有文件都在同一目录中。我用python setup build_ext --inplace编译。然后通过运行./run,我收到以下错误:

Exception AttributeError: "'Computation.Computation' object has no attribute 'Add'" in 'Solver.Solver.Solve' ignored

我有两种方法来解决这个问题:

  1. 如果我将Add()cdef改为cpdef函数,我就不会再得到这个错误。但是在本例中,Solve()调用cpdef,与cdef相比,它有一个开销。我想避免对Add()使用cpdef,因为在实际的代码中,Add()是一个昂贵的代码,并且可以多次调用。你知道吗
  2. 如果在Solver类中,我没有将Comp对象声明为成员数据,而只是在Solve()函数中声明它,则不会出现此错误。像这样:

    # filename: Solver.pyx
    
    from Computation cimport Computation
    cdef class Solver:
        # No member data here.
        cpdef double Solve(self):
            # We declare Comp here instead:
            Comp = Computation()
            Result =  Comp.Add(4)
            return Result
    

但我更希望Comp也成为Solver的成员。我的猜测是,通过在python代码中声明Compdef __cinit__(self),不再声明cdef函数。你知道吗

所以,我的问题是,如何共享扩展类型的声明,而扩展类型本身就是另一个类的成员数据?也就是说,cython扩展类型如何在__cinit__()中声明?你知道吗


Tags: 函数代码selfadd声明成员resultfilename
1条回答
网友
1楼 · 发布于 2024-05-13 14:19:26

我自己找到的。就在Solver.pyx行中

cdef object Comp

应改为

cdef Computation Comp

这里的对象是显式类型化的。 通过这种方法,扩展类型的cdef方法可以在其他地方访问。你知道吗

相关问题 更多 >