Python 和冲突的模块名称

Python and conflicting module names

似乎如果一个文件被称为 io.py 并且它导入 scipy.ndimage,后者不知何故最终无法找到它自己的子模块,也称为 io:

$ echo "import scipy.ndimage" > io.py
$ python io.py 
Traceback (most recent call last):
  File "io.py", line 1, in <module>
    import scipy.ndimage
  File "/usr/lib/python2.7/dist-packages/scipy/__init__.py", line 70, in <module>
    from numpy import show_config as show_numpy_config
  File "/usr/lib/python2.7/dist-packages/numpy/__init__.py", line 153, in <module>
    from . import add_newdocs
  File "/usr/lib/python2.7/dist-packages/numpy/add_newdocs.py", line 13, in <module>
    from numpy.lib import add_newdoc
  File "/usr/lib/python2.7/dist-packages/numpy/lib/__init__.py", line 22, in <module>
    from .npyio import *
  File "/usr/lib/python2.7/dist-packages/numpy/lib/npyio.py", line 4, in <module>
    from . import format
  File "/usr/lib/python2.7/dist-packages/numpy/lib/format.py", line 141, in <module>
    import io
  File "/tmp/rm_me/io.py", line 1, in <module>
    import scipy.ndimage
  File "/usr/lib/python2.7/dist-packages/scipy/ndimage/__init__.py", line 172, in <module>
    from .filters import *
  File "/usr/lib/python2.7/dist-packages/scipy/ndimage/filters.py", line 37, in <module>
    from scipy.misc import doccer
  File "/usr/lib/python2.7/dist-packages/scipy/misc/__init__.py", line 45, in <module>
    from .common import *
  File "/usr/lib/python2.7/dist-packages/scipy/misc/common.py", line 10, in <module>
    from numpy import exp, log, asarray, arange, newaxis, hstack, product, array, \
ImportError: cannot import name exp

这是 SciPy 中的错误,还是我使用 Python 错误?

Update:我认为如果 import mod2 in mod1 解析的路径相对于 mod1 而不是相对于任何人,那么行为就不那么令人惊讶了进口 mod1.

简单的解决方法是避免命名模块 io,因为它与核心库模块名称冲突。

这不是 numpy 中的真正错误,而是用户错误:就像我们不应该使用 list 作为变量名一样,因为它隐藏了内置的 list 名称,我们不应该使用io 作为模块名称,因为它隐藏了核心库 io 模块名称。

看这部分:

  File "/usr/lib/python2.7/dist-packages/numpy/lib/format.py", line 141, in <module>
    import io

此处 numpy 尝试导入 io module。这是为了找到 stdlib io 因为绝对导入 - 一个 numpy 子模块会加载 relative 导入就像你在回溯中看到的那样有另一行开始 from .npyio import *

当然是先找到自己的io.py模块,因为在当前工作目录中一般是第一个进入sys.path。哎呀!

您使用的 python 有误。

在创建任何顶级 python 模块或包之前,您应该确保还没有同名的模块或包。

这里最好的解决方案是不使用顶级模块,而是将所有内容放在以您的项目命名的单个顶级包中(即包含 __init__.py 文件的目录)。

要检查顶层模块或包是否存在,您可以尝试在解释器中 importing,或从 shell 运行 pydoc name


值得注意的是,如果包使用绝对样式的导入语法来执行相对导入,则可能会发生非常相似的错误,这不是您的错。此 "feature" 在 Python3 中删除。