我想使用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
我有两种方法来解决这个问题:
Add()
从cdef
改为cpdef
函数,我就不会再得到这个错误。但是在本例中,Solve()
调用cpdef
,与cdef
相比,它有一个开销。我想避免对Add()
使用cpdef
,因为在实际的代码中,Add()
是一个昂贵的代码,并且可以多次调用。你知道吗如果在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代码中声明Comp
,def __cinit__(self)
,不再声明cdef
函数。你知道吗
所以,我的问题是,如何共享扩展类型的声明,而扩展类型本身就是另一个类的成员数据?也就是说,cython扩展类型如何在__cinit__()
中声明?你知道吗
我自己找到的。就在
Solver.pyx
行中应改为
这里的对象是显式类型化的。 通过这种方法,扩展类型的
cdef
方法可以在其他地方访问。你知道吗相关问题 更多 >
编程相关推荐