Python导入阴影在3.4.6和3.5.2之间不同

Nie*_*ran 7 python import shadowing python-internals

版本3.4.6和3.5.2之间的Python导入阴影似乎不同:

$ cat time.py
from time import time
$ pyenv global 3.4.6
$ python -V
Python 3.4.6
$ python time.py 
Traceback (most recent call last):
  File "time.py", line 1, in <module>
    from time import time
  File "/home/vagrant/tmp/time.py", line 1, in <module>
    from time import time
ImportError: cannot import name 'time'
$ pyenv global 3.5.2 
$ python -V
Python 3.5.2
$ python time.py
$ echo no error
no error
Run Code Online (Sandbox Code Playgroud)

问题1:为什么......那些东西?

问题2:更新日志中有什么内容吗?我找不到任何东西......

vau*_*tah 6

文件说明了这一点

spam导入命名模块时,解释器首先搜索具有该名称的内置模块.如果未找到,则会搜索spam.py由变量给出的目录列表中指定的文件sys.path.

(强调我的)

time 不是Python 3.4中的内置模块模块,但在Python 3.5中有所改变:

me@temp:~$ python3.4 -c 'import sys; print("time" in sys.builtin_module_names)'
False
me@temp:~$ python3.5 -c 'import sys; print("time" in sys.builtin_module_names)'
True
Run Code Online (Sandbox Code Playgroud)

您可以在此处看到引入更改的修补程序(与问题5309相关).考虑到更改日志提到问题5309,但没有说任何重新.在time模块中,可以肯定地说这个改变是副作用,是CPython的一个实现细节.

由于timeCPython 3.4中不是内置模块,并且第一个目录sys.path是当前脚本目录,因此from time import time尝试timetime.py文件中导入属性,但失败并抛出ImportError.

在CPython 3.5中time 一个内置模块.根据上面的引用,运行from time import time成功导入内置模块,而不搜索模块sys.path.

如果您从标准库中隐藏非内置模块,则两个CPython版本都会引发相同的错误,例如inspect:

me@temp:~$ cat inspect.py 
from inspect import signature
me@temp:~$ python3.4 -c 'import inspect'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/me/inspect.py", line 1, in <module>
    from inspect import signature
ImportError: cannot import name 'signature'
me@temp:~$ python3.5 -c 'import inspect'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/me/inspect.py", line 1, in <module>
    from inspect import signature
ImportError: cannot import name 'signature'
Run Code Online (Sandbox Code Playgroud)