以下行在Python 3中是做什么的?
>>> from . import *
它不输出任何内容,而我在Python 3.7.3中可以看到的唯一变化如下:
>>> '__warningregistry__' in locals()
False
>>> from . import *
>>> '__warningregistry__' in locals()
True
>>> locals()['__warningregistry__']
{'version': 0}
这可能是警告模块的一部分,它表明某个警告未打印,但模块__warningregistry__
中的documentation mentions only a variable warnings
。
文档解释了from . import foo
works的方式以及from bar import *
works的方式,但是我找不到关于from . import *
的任何信息。有人可能希望将__init__.py
中的所有名称都加载到当前名称空间中(就像from bla import *
对bla.py
所做的那样),但事实并非如此,而且事实并非如此。在__name__ == '__main__'
(脚本和终端)时才有意义。
Python 2的行为与我预期的更为相似:
>>> # Python 2.7.16
>>> from . import *
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Attempted relative import in non-package
PEP 328颇具启发性,但也无法回答我的问题。
答案 0 :(得分:4)
如果__main__
是脚本或交互式会话,则.
是__main__
程序包本身:
$ python3 -c 'from . import float'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: cannot import name 'float' from '__main__' (unknown location)
这使from . import *
暂时没有了,并添加了__warningregistry__
作为import
机制的副作用。
PEP 366对来自__main__
的相对导入进行了特殊设置。引入__package__
进行相对包名称查找,和指定__main__. __package__
具有特殊值None
。
此外,模块导入规范__main__.__spec__
may be None
-即在交互式外壳中或在执行脚本时。
事实证明,带有__package__ = __spec__ = None
的 any 模块会将.
视为自身:
$ cat test.py
__package__ = __spec__ = None
from . import float
$ python3 -c 'import test'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/mfischer/PycharmProjects/lispy/test.py", line 2, in <module>
from . import float
ImportError: cannot import name 'float' from 'test' (./test.py)
__warningregistry__
is added,因为有一个hidden warning from the missing attributes。默认情况下,它是不显示的,但是您可以使用all warning enabled看到它:
$ python3 -Wa -c 'from . import float'
-c:1: ImportWarning: can't resolve package from __spec__ or __package__, falling back on __name__ and __path__
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: cannot import name 'float' from '__main__' (unknown location)