2011-03-05 71 views
10

我在编译不同包中的cdef-ed类型时遇到了问题,我无法在cython文档中找到解释。在不同的包中编译依赖的pyx文件

我有此setup.py在我蟒SRC树的根:

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Distutils import build_ext 

setup(
    cmdclass = {'build_ext': build_ext}, 
    ext_modules = [ 
     Extension("flink.pytk.defs.FragIdx", 
     sources = ["flink/pytk/defs/FragIdx.pyx"]), 
     Extension("flink.pytk.fragments.STK_idx", 
     sources = ["flink/pytk/fragments/STK_idx.pyx"]) 
     ] 
) 

FragIdx是CDEF-ED型,在定义弗林克/ pytk/DEFS/FragIdx.pyx:

cdef class FragIdx: 
    cdef public FragIdx parent 
    cdef public FragIdx root 
    cdef public tuple label 
    ... 

而且STK_idx是FragIdx的延伸,在弗林克定义/ pytk /片段/ STK_idx.pyx:

from flink.pytk.defs.FragIdx import FragIdx 
cdef class STK_idx(FragIdx): 
    ... 

当我试图编译USI纳克在文章开头列出的setup.py,FragIdx编译没事,但是当涉及到STK_idx我收到以下错误信息:

flink/pytk/fragments/STK_idx.pyx:5:5: 'FragIdx' is not a type name 

请注意,我的源代码树的根目录列在$ PYTHONPATH中。

我真的很感激,如果任何人都可以摆脱这一点,非常感谢!

丹尼尔

回答

8

哦,那么,对于那些有类似的问题,看起来也许我找到了答案。

我期待python自动扫描编译到共享库FragIdx.so中的符号,而不是像这样的信息必须显式提供为.pxd文件(在Cython运行后它变成C头文件)。

基本上有过程中涉及的两个步骤:

  1. 定义(.pxd)文件为超类的创作;
  2. 通过子类模块中的cimport(而不是import)导入超类定义。

所以,使它更通用。

假设您已经在模块pkg1.mod1中定义了您的cdef-ed类型A。那么你可以在pkg2.mod2中输入B这个类型,它的子类是A

你的目录结构会是这个样子:

pkg1/ 
    mod1.pyx 
    mod1.pxd 
pkg2/ 
    mod2.pyx 
    mod2.pxd 

pkg1/mod1.pxd你会,说:

cdef class A: 
    cdef int a 
    cdef int b 

而且在pkg1/mod1.pyx你会提供您的类的方法。 在pkg2/mod2.pxd,你会:

from pkg1.mod1 cimport A #note "cimport"!! 
cdef class B(A): 
    cdef ... # your attributes here 

再次,在pkg2/mod2.pyx你必须cimport再次符号:

from pkg1.mod1 cimport A #note "cimport"!! 
cdef class B(A): 
    ... # your methods here 

有趣的是,如果你只是想在你的Python使用A代码,而不是使用它来定义子类型,不需要定义文件mod1.pxd。这与创建扩展类型时需要C编译器可用的定义相关,而运行Python代码时没有这个问题,但由于它不是非常直观,所以指出它可能很重要出。

该信息实际上在Cython docs中可用,但也许它可能会更加明确。

希望这些信息可以为别人节省一些。