2

这个问题与以下内容有一些相似之处:

嵌套的 Python C 扩展/模块?

只有轻微的扭曲。在这里,我不是想混合两个 C-ext,而是一个 C-ext 和一个常规的 python 子模块。

C-extension 有没有办法在符号“module.so”和子模块中的符号之间共享模块命名空间?

我的模块结构如下所示:

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'

如您所见, after dir(facs), build, queryandremove消失了,并且galaxy 没有正确导入,除非我执行 afrom facs.utils import galaxy而不是重新使用初始 import 语句并直接访问 via 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文件实际上被复制到顶级目录,但是在那里触摸它不会影响上述导入行为。

有任何想法吗?提前致谢!

4

1 回答 1

0

请注意,您首先导入的是 so 文件,而不是 facs 包。你是否在 facs 包源目录上运行你的 python 控制台?

尝试走出包目录,一切都会变得有意义。

此外,下一个导入并没有说明 facs 目录后面的所有模块都将被导入:

>> import facs
>> dir (facs)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

你必须在每个__init__.py文件中设置你的导入,例如,如果你想在你的文件中导出一些符号,你的.so文件import facs中应该有以下内容__init__.py

>> from _facs import function_name, function_name .....

然后,当你import facs,它会为你导入这些功能。

为您的子包实用程序采用相同的模式。

我还建议将您的facs.so文件重命名为_facs.so文件以避免包名称和模块名称之间的名称冲突。

于 2013-03-01T17:32:48.213 回答