我已经到了一个需要正确目录结构的项目。我正在尝试安排这个并在使用我的cython扩展类时获得ImportError
。
目录结构如下:
.
├── __init__.py
├── Makefile
├── README.rst
├── setup.py
├── src
│ ├── foo.pxd
│ ├── foo.pyx
│ ├── __init__.py
│ └── metafoo.pyx
└── test
├── test_foo.py
└── test_metafoo.py
this github repo可以找到所有文件的内容(在撰写本文时的提交e635617中)。
我的setup.py
如下所示:
from setuptools import setup, Extension, Command
from Cython.Build import cythonize
SRC_DIR = "src"
PACKAGES = [SRC_DIR]
ext_foo = Extension(SRC_DIR + ".foo",
[SRC_DIR + "/foo.pyx"]
)
ext_meta = Extension(SRC_DIR + ".metafoo",
[SRC_DIR + "/metafoo.pyx"]
)
EXTENSIONS = cythonize([ext_foo, ext_meta])
setup(
name = 'minimalcriminal',
packages=PACKAGES,
ext_modules=EXTENSIONS
)
复杂性似乎在于metafoo.pyx
中的扩展类使用foo.pyx
中的扩展类。
使用python setup.py build_ext --inplace
构建后,test_foo.py
程序运行正常:
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
import src.foo as foo
somefoo = foo.Foo(2)
somefoo.special_print()
从cyproj/test
和cyproj
目录运行时:
/cyproj$ python test/test_foo.py
The value of somefield is: 2
和
/cyproj/test$ python test_foo.py
The value of somefield is: 2
但test_metafoo.py
在cyproj/test
目录中运行时崩溃:
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
import src.foo as foo
import src.metafoo as metafoo
lotsafoo = [foo.Foo(i) for i in range(4)]
mf = metafoo.MetaFoo(lotsafoo)
mf.special_print()
显示消息:
ubuntu@ubuntu-UX21E:/projects/cyproj/test$ python test_metafoo.py
Traceback (most recent call last):
File "test_metafoo.py", line 6, in <module>
import src.metafoo as metafoo
File "cyproj/src/foo.pxd", line 6, in init cyproj.src.metafoo (src/metafoo.c:1154)
ImportError: No module named cyproj.src.foo
但是从父cyproj
目录正确运行:
/cyproj$ python test/test_metafoo.py
The value of somefield is: 0
The value of somefield is: 1
The value of somefield is: 2
The value of somefield is: 3
我真的不明白是什么导致了这些错误的不同行为。如果我无法在import src.foo
中使用test_metafoo.py
,为什么它会在test_foo.py
中有效?
同样,如果我在父目录中打开一个交互式会话并尝试导入所有:
In [1]: from src import *
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-7b8bc2c1dfb9> in <module>()
----> 1 from src import *
/projects/cyproj/cyproj/src/foo.pxd in init cyproj.src.metafoo (src/metafoo.c:1154)()
ImportError: No module named cyproj.src.foo
src/__init__.py
看起来像:
__all__ = ["foo", "metafoo"]
我认为允许导入所有...
答案 0 :(得分:1)
从项目根目录中删除__init__.py
文件并更改test_foo.py
和test_metafoo.py
后,我能够编译并测试您的包。
sys.path.append(os.path.abspath("."))
sys.path.append(os.path.abspath("../"))