.pyx 和 .pxd 文件在子目录中时的 Cython 0.23.4 AttributeError

Posted

技术标签:

【中文标题】.pyx 和 .pxd 文件在子目录中时的 Cython 0.23.4 AttributeError【英文标题】:Cython 0.23.4 AttributeError when .pyx and .pxd files in subdirectory 【发布时间】:2015-10-22 21:49:11 【问题描述】:

我将 Cython 升级到版本 0.23.4,当我将 .pyx 和 .pxd 文件放在工作目录的子目录中时,我的代码现在会导致 AttributeError。 包含错误的最小示例如下:

工作目录中的主要python文件:

import pyximport;
import os,sys; 
pyximport.install()
sys.path.insert(0, os.getcwd()+'/pxd')
sys.path.insert(0, os.getcwd()+'/pyx')
from X import *

xObj = X(5)

pyx/X.pyx(即在子目录pyx/中):

cdef class X:
    def __init__(self,var):
        self.var = var

pxd/X.pxd(即在子目录 pxd/ 中):

cdef class X:
    cdef public int var

运行 Main.py 会出现以下错误:

AttributeError: 'X.X' object has no attribute 'var'

注意,如果我将 X.pyx 和 X.pxd 文件移动到我的工作目录中,代码运行良好。但是由于文件很多,这样做很不方便。

在子目录中有 X.pyx 和 X.pxd 的同时,我可以做些什么来运行代码?

【问题讨论】:

【参考方案1】:

Cython 期望 .pyx 和 .pxd 文件彼此位于同一目录中(不一定是您的工作目录)。就目前而言,我认为您只导入了“X.pyx”,并没有意识到“X.pxd”与之相关。

因此,您可以创建一个名为“cython_files”的目录(以使您的文件远离工作目录),然后在该目录中放置“X.pxd”和“X.pyx”。然后,您可以将“cython_files”添加到您的路径中,并且不会出现任何属性错误。

更好的是,您可以将“__init__.py”添加到您的“cython_files”目录,然后将其视为 Python 模块,您可以执行from cython_files.X import X,而不必在路径中添加任何内容。

为清楚起见进行编辑: @roenic's answer 确定了相同的问题,但提出了一个稍微不同的解决方案(我怀疑这是可行的) - 这个答案认为 OP 真的不应该将他们的文件组织在他们做的方式,而不是试图解决它。

【讨论】:

【参考方案2】:

问题是如果您将头文件 (.pxd) 拆分到不同的目录中,Cython 找不到您的头文件,除非您明确导入声明

from pxd_file cimport class_declaration 

假设pxd_file 的路径对编译器可见。在您给出的示例中,这只是转换为

from X cimport X

看看这些 Cython 的 internal examples。

【讨论】:

这似乎并不能解决 AttributeError。我的测试代码在 Cython 升级之前运行完美。所以我认为问题一定出在生成的 .c 文件中。 您发布的工作示例在我的机器上运行时没有任何警告,正如我所建议的那样,我正在使用 Cython 0.23.4。很难猜测您的实际代码中存在什么问题。也许您可以删除 .c 文件并重新编译整个内容。那应该可以解决问题。如果没有,那么如果您认为这是 0.23.4 版本的问题,您可以随时在 Cython 邮件列表上报告错误。

以上是关于.pyx 和 .pxd 文件在子目录中时的 Cython 0.23.4 AttributeError的主要内容,如果未能解决你的问题,请参考以下文章

Cython 中的 C++ 指针

『Python CoolBook』Cython

python / cython编译pyx:致命错误:capsule.h:没有这样的文件或目录

如何通过cython接口返回对象引用的c ++函数

长运通CYT3000B/CYT1000B线性恒流

将 cython 函数与 cython 方法传递给 scipy.integrate