__init__.pyx 的 Cython 包:可能吗?

Cython package with __init__.pyx: Possible?

是否可以使用 __init__.pyx(编译为 __init__.so)创建 Python 2.7 包?如果是这样怎么办?我没有运气让它工作。

这是我尝试过的:

上面有以下行为:

$ python -c 'import foo; foo.hello_world()'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named foo

我看到 Python Hg 存储库的 Python issue #15576 which was fixed by this Hg commit. Looking at the equivalent Git commit in the Git mirror,我看到可以从 Python v2.7.5 标签(以及所有后续的 v2.7.x 版本)。有回归吗?

尝试使用相对导入。

__init__中:

from . import bar

也可能是from . import foo。好久没用 python 2 cython 了。

根据 this really old mailing list post 如果您还有一个 __init__.py 文件(__init__.py 文件未被使用,但对于将目录视为模块,因此要加载 __init__.so 文件)。

如果我加上__init__.py:

# an exception just to confirm that the .so file is loaded instead of the .py file
raise ImportError("__init__.py loaded when __init__.so should have been loaded")

那么您的示例适用于 Linux Python 2.7.3:

$ python -c 'import foo; foo.hello_world()'
hello world
blah

这具有越野车角落案例的所有迹象,因此可能不推荐。请注意,在 Windows 这似乎对我不起作用

ImportError: DLL load failed: %1 is not a valid Win32 application.

附录(一些额外的上下文):

似乎没有明确记录此行为。在 the original description of packages 大约 Python 1.5 时代,他们说:

without the __init__.py, a directory is not recognized as a package

Tip: the search order is determined by the list of suffixes returned by the function imp.get_suffixes(). Usually the suffixes are searched in the following order: ".so", "module.so", ".py", ".pyc". Directories don't explicitly occur in this list, but precede all entries in it.

观察到的行为肯定与此一致 — __init__.py 需要将目录视为一个包,但 .so 文件优先于 .py 文件加载 — 但它很难明确。

从 Cython 的角度来看,这种行为似乎被用于编译标准库(在这种情况下 __init__.py 将始终存在),或者在给出的测试用例中 https://github.com/cython/cython/blob/master/tests/build/package_compilation.srctree(还有其他一些例子)。在这些文件中,"srctree" 文件看起来被扩展到包含 __init__.py(和其他文件)的各种文件夹中,然后进行编译。有可能只有 __init__.so 根本就没有经过测试。