共享cython扩展类型的声明,它是另一种扩展类型

时间:2016-12-18 20:44:07

标签: python cython

我想使用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()调用的cpdefcdef相比具有开销。我希望避免对cpdef使用Add(),因为在实际代码中,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
    
  3. 但我更喜欢Comp成为Solver的成员。我的猜测是,通过在python代码Comp中声明def __cinit__(self)cdef函数不再被声明。

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

1 个答案:

答案 0 :(得分:0)

自己找到它。只需在Solver.pyx

cdef object Comp

应改为

cdef Computation Comp

这里明确地输入了对象。 有了这个,扩展类型的cdef方法可以在其他地方访问。