python - 加载 numpy 时本地脚本与内置模块冲突

标签 python numpy anaconda conda

有很多关于相对/绝对导入问题的帖子,其中大部分是关于 Python 2 和/或导入子模块的。 这不是我的情况:

  • 我使用的是 Python 3,所以绝对导入是默认的;
  • (我也用 Python 2 重现了这个问题);
  • 我不是要从另一个子模块或任何其他复杂情况中导入子模块。我只是想在脚本中import numpy

我的问题很简单:

.
└── foo
    ├── a.py
    └── math.py

1 directory, 2 files

其中a.py只包含import nupmy,而math.py包含x++(故意无效) .

在这种情况下,运行 python3 foo/a.py 会导致错误,因为 NumPy 似乎无法导入标准的 math 模块:

Traceback (most recent call last):
  File "foo/a.py", line 1, in <module>
    import numpy
  File "/path/to/Anaconda3/lib/python3.6/site-packages/numpy/__init__.py", line 158, in <module>
    from . import add_newdocs
  File "/path/to/Anaconda3/lib/python3.6/site-packages/numpy/add_newdocs.py", line 13, in <module>
    from numpy.lib import add_newdoc
  File "/path/to/Anaconda3/lib/python3.6/site-packages/numpy/lib/__init__.py", line 3, in <module>
    import math
  File "/private/tmp/test-import/foo/math.py", line 1
    x++
      ^
SyntaxError: invalid syntax

我对 Python 相对缺乏经验,但这对我来说像是一个错误。我认为像 Python 3 中的 import math 这样的语句表现为绝对导入;本地文件如何与标准模块冲突?我做错了什么吗?

澄清一下,令我惊讶的是 NumPy 无法使用 import math 加载标准数学模块,因为我的本地文件夹中有一个名为 math. py请注意,我从未尝试自己导入该模块。


编辑

这似乎是 conda 特有的问题(与 Anaconda 和 Miniconda 一起复制)。我正在使用 Anaconda 5.2.0(在 OSX 10.13.6 上),评论中的人已经能够使用不同版本的 python/anaconda 和不同的系统进行重现。

我能够重现这个问题:

  • Anaconda3 v5.2.0,在 conda 环境中使用 python 3.4、3.5、3.6 和 3.7,或者简单地使用默认二进制文件(即 /path/to/anaconda3/bin).
  • Miniconda2 和 Miniconda3(需要手动安装 numpy),同样在 conda 环境之内或之外。
  • 干净的 Homebrew 安装 brew install python

在所有情况下,内置模块看起来都可能不完整:

> python3 -c "import sys; print(sys.builtin_module_names)"
('_ast', '_codecs', '_collections', '_functools', '_imp', '_io', '_locale', '_operator', '_signal', '_sre', '_stat', '_string', '_symtable', '_thread', '_tracemalloc', '_warnings', '_weakref', 'atexit', 'builtins', 'errno', 'faulthandler', 'gc', 'itertools', 'marshal', 'posix', 'pwd', 'sys', 'time', 'xxsubtype', 'zipimport')

> python2 -c "import sys; print sys.builtin_module_names"
('__builtin__', '__main__', '_ast', '_codecs', '_sre', '_symtable', '_warnings', '_weakref', 'errno', 'exceptions', 'gc', 'imp', 'marshal', 'posix', 'pwd', 'signal', 'sys', 'thread', 'xxsubtype', 'zipimport')

重现此问题

确保你有一个可以导入 numpy 的 Python 版本。打开终端并输入:

D=$(mktemp -d)                      # temporary folder
pushd "$D"                          # move there 
mkdir foo                           # create subfolder
echo 'import numpy' >| foo/a.py     #   script a.py
echo 'x++' >| foo/math.py           #   script math.py (invalid)
python foo/a.py                     # run a.py
popd                                # leave temp folder

最佳答案

“绝对导入”并不意味着“标准库导入”。这意味着 import math 总是尝试导入 math 模块,而不是在导入发生在内部时先尝试 currentpackage.math 的旧行为一套。它意味着 Python 在确定 math 模块的位置时将跳过 sys.path 上的非 stdlib 条目。在您的情况下,根据 Python 导入系统的规则,您的 math.pymath 模块。


您在该行找到的教程链接

When a module named spam is imported, the interpreter first searches for a built-in module with that name.

指的是直接编译成 Python 可执行文件的模块,例如 sys。这些模块在它们的 repr 中说 built-in:

>>> sys
<module 'sys' (built-in)>

您可以在sys.builtin_module_names 中看到所有此类模块的名称。 .对我来说,这些名字是

>>> sys.builtin_module_names
('_ast', '_codecs', '_collections', '_functools', '_imp', '_io', '_locale', '_operator', '_signal', '_sre', '_stat', '_string', '_symtable', '_thread', '_tracemalloc', '_warnings', '_weakref', 'atexit', 'builtins', 'errno', 'faulthandler', 'gc', 'itertools', 'marshal', 'posix', 'pwd', 'sys', 'time', 'xxsubtype', 'zipimport')

math 在这个意义上不是内置的。

关于python - 加载 numpy 时本地脚本与内置模块冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51878397/

相关文章:

python - 将 Numpy 数组保存为图像

python - 从磁盘中删除外键上的图像

python - PyTorch DataLoader 在每个时期使用相同的随机变换

python - Pandas (Excel): How to read full value with zeros in start?

python - 如何使用 python 中的循环将键和值分配给字典?

python - 如果该列大于所述日期,如何绕过此错误以使该列为零? "TypeError: invalid type promotion "

python - 如何累计 "all"

anaconda - Conda 返回解决环境 : Done -- hangs with all processes

由于最近的更新,Azure synapse apache Spark池无法安装geopandas

python - 如何在 Anaconda 版本中安装 theano。 2.1 适用于 Python 3.4 的 Windows 64 位?