这个问题有一些相似之处:
嵌套Python C扩展/模块?
只是稍微扭曲一下。在这里,我不是试图混合两个C-ext,而是一个C-ext和一个普通的python子模块。
是否有一种方法可以让c扩展在符号"module. module"之间共享模块命名空间?那么,子模块中存在的那些呢?
我的模块结构像这样:
facs/
facs/
__init__.py
setup.py
facs.so
[*.c files]
utils/
__init__.py
galaxy.py
如果我从层次结构中删除"utils",我可以导入facs并查看facs.so
方法:
>>> import facs
>>> dir(facs)
['__doc__', '__file__', '__name__', '__package__', 'build', 'query', 'remove']
但是当我把utils子模块放回去并尝试导入不同的部分时,一个命名空间似乎掩盖了另一个(utils
掩盖了facs.so
导出的符号):
>>> import facs
>>> dir(facs)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
>>> import facs.utils
>>> facs.utils.galaxy.rsync_genomes("phix")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'galaxy'
>>> from facs.utils import galaxy
>>> galaxy.rsync_genomes("phix")
'Hello world'
可以看到,在dir(facs)
之后,build
、query
和remove
都不见了,galaxy
不能正确导入,除非我做一个from facs.utils import galaxy
代替重用初始的import语句并直接通过facs.utils.galaxy.rsync_genomes()
进行访问。
>>> import facs
>>> dir(facs)
['__doc__', '__file__', '__name__', '__package__', 'build', 'query', 'remove'
, 'utils'] <--- (Directly accessible from "facs")
>>> facs.utils.galaxy.rsync_genomes("phix")
'Hello world'
(目前正在开发中)代码位于:
https://github.com/brainstorm/facs/tree/develop以防有人想自己尝试一下。我正在使用virtualenvs和我的$PYTHONPATH看起来是正确的:
/home/roman/.venvburrito/lib/python:
/home/roman/.virtualenvs/py27/lib/python2.7/site-packages
安装似乎也很成功:
cd ~/.virtualenvs/py27/lib/python2.7/site-packages/facs-2.0dev-py2.7.egg/
(py27)$ ls
EGG-INFO facs.py facs.pyc facs.so utils/
似乎没有__init__.py
文件实际上被复制到顶级目录,但是否触摸它并不影响上述导入行为。
任何想法?提前感谢!
请注意,您首先导入的是so文件,而不是facs包。您是否在facs包源目录上运行python控制台?
尝试到包目录之外,一切都会有意义。
同样,next import并没有说facs目录后面的所有模块都将被导入:
>> import facs
>> dir (facs)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
您必须在每个__init__.py
文件中设置导入,例如,如果您想在import facs
文件中导出.so
文件中的一些符号,您应该在__init__.py
文件中包含以下内容:
>> from _facs import function_name, function_name .....
然后,当您输入import facs
时,它会为您导入这些函数。
对子包utils采用相同的模式。
我还建议将您的facs.so
文件重命名为_facs.so
文件,以避免包名和模块名之间的名称冲突。