关于相对/绝对导入问题的文章很多,其中大多数是关于Python 2和/或导入子模块的。 这不是我的情况:
import numpy
。我的问题很简单:
.
└── foo
├── a.py
└── math.py
1 directory, 2 files
其中a.py
仅包含import nupmy
,而math.py
包含x++
(故意无效)。
在这种情况下,由于NumPy似乎无法导入标准python3 foo/a.py
模块,因此运行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和不同的系统进行复制。
我能够通过以下方式重现此问题:
conda
环境中使用python 3.4、3.5、3.6和3.7,或仅使用默认二进制文件(即/path/to/anaconda3/bin
)。numpy
),还是在conda
环境之内还是之外。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
答案 0 :(得分:0)
“绝对导入”并不意味着“标准库导入”。这意味着import math
始终尝试导入math
模块,而不是如果导入发生在包内则先尝试currentpackage.math
的旧行为。 不是并不意味着Python在确定sys.path
模块的位置时将跳过math
上的非stdlib条目。根据您的情况,根据Python导入系统的规则,您的math.py
是math
模块。
在该行中找到的教程链接
导入名为垃圾邮件的模块时,解释器首先搜索具有该名称的内置模块。
指的是直接编译为Python可执行文件的模块,例如sys
。这样的模块在其built-in
中说repr
:
>>> 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
不是内置的。