Python C-ext命名空间与常规Python子模块混合



这个问题有一些相似之处:

嵌套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)之后,buildqueryremove都不见了,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文件,以避免包名和模块名之间的名称冲突。

最新更新