是否可以使用__init__.pyx
创建Python 2.7包(编译为__init__.so
)?如果是这样的话?我没有运气好运。
以下是我的尝试:
setup.py
:
#!/usr/bin/env python
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
foo = Extension(name='foo.__init__', sources=['foo/__init__.pyx'])
bar = Extension(name='foo.bar', sources=['foo/bar.pyx'])
setup(name='foo',
packages = ['foo'],
cmdclass={'build_ext':build_ext},
ext_modules = [foo, bar])
foo/__init__.pyx
:
import foo.bar
cpdef hello_world():
print "hello world"
foo.bar.blah()
foo/bar.pyx
:
cpdef blah():
print "blah"
以上有以下行为:
$ python -c 'import foo; foo.hello_world()'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named foo
我看到了由Python issue #15576修复的this Hg commit。查看Python Hg存储库的equivalent Git commit中的Git mirror,我看到可以从Python v2.7.5标记(以及所有后续的v2.7.x版本)访问提交。有回归吗?
答案 0 :(得分:14)
根据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.
附录(有一点额外背景):
这种行为似乎没有明确记录。在Python 1.5时代的the original description of packages中,他们说:
没有
__init__.py
,目录不会被识别为包
和
提示:搜索顺序由函数
imp.get_suffixes()
返回的后缀列表确定。通常按以下顺序搜索后缀:&#34; .so&#34;,&#34; module.so&#34;,&#34; .py&#34;,&#34; .pyc&#34; 。目录没有明确出现在此列表中,但在其中的所有条目之前。
观察到的行为肯定与此一致 - __init__.py
将目录视为包,但.so文件优先加载到.py文件 - 但它几乎不明确。
从Cython的角度来看,这种行为似乎被用来编译标准库(在这种情况下__init__.py
总是存在),或者在给出https://github.com/cython/cython/blob/master/tests/build/package_compilation.srctree的测试用例中(和其他几个例子也是如此)。在这些&#34; srctree&#34;文件看起来要扩展为包含__init__.py
(和其他文件)然后编译的各种文件夹。可能只有__init__.so
只是从未测试过。
答案 1 :(得分:-3)
尝试使用相对导入。
__init__
中的:
from . import bar
也可能是from . import foo
。 Haven在一段时间内没有使用python 2 cython。