【问题标题】:Python C-ext namespace mixed with regular python submodules?Python C-ext 命名空间与常规 python 子模块混合?
【发布时间】:2013-03-01 15:31:26
【问题描述】:

这个问题与:

Nested Python C Extensions/Modules?

只有轻微的扭曲。在这里,我不是要混合两个 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'

如你所见,dir(facs)buildqueryremove 消失了,galaxy 除非我改为使用from facs.utils import galaxy,否则无法正确导入 重新使用初始导入语句并直接通过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文件实际上被复制到顶级目录,但在那里触摸它不会影响上述导入行为。

有什么想法吗?提前致谢!

【问题讨论】:

  • 您是否尝试将facs.so 重命名为其他名称?尝试为包和 .so 使用不同的名称
  • .so 文件是在编译/安装 python 模块时生成的,我自己不会生成它...抱歉,如果不清楚:-S

标签: python namespaces python-import python-c-extension


【解决方案1】:

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

尝试到包目录之外,一切都会变得有意义。

另外,下一次导入并不是说你的 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 时,它会为您导入这些功能。

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

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

【讨论】:

  • 您好!很高兴在这里见到你!我实际上提出了您的建议,但这似乎并不能解决我的问题 :_S: github.com/brainstorm/facs/commit/…
  • 在上面的提交之后,我得到“导入错误:没有名为 facs 的模块”,所以我无法加载任何符号 :-/ 再次感谢您查看! :D
  • 抱歉,facs/__init__.py 应该是 """from facs._facs import ...""" 并且应该可以工作...
  • 文件 "/home/roman/dev/facs/facs/__init__.py",第 1 行,在 from facs._facs import build, query, remove ImportError: 动态模块没有定义初始化函数 (init_facs)跨度>
  • 我观察到我刚刚编辑的 facs/__init__.py 文件没有被复制到 .virtualenv 目录:$ ls ~/.virtualenvs/py27/lib/python2.7/site -packages/facs-2.0dev-py2.7-linux-x86_64.egg/ EGG-INFO _facs.py _facs.pyc _facs.so utils .... 但结果是一样的,模块根本没有被导入(ImportError:没有名为 facs 的模块)。
猜你喜欢
  • 2014-01-26
  • 2015-06-26
  • 2016-05-21
  • 1970-01-01
  • 2022-06-17
  • 2012-01-15
  • 2023-01-30
  • 1970-01-01
  • 2011-11-26
相关资源
最近更新 更多