简体   繁体   中英

What does 'from dot import asterisk' do in Python 3?

Question

What does the following line do in Python 3?

>>> from . import *

What I found out so far...

It does not output anything and the only change I can see in Python 3.7.3 is the following:

>>> '__warningregistry__' in locals()
False
>>> from . import *
>>> '__warningregistry__' in locals()
True
>>> locals()['__warningregistry__']
{'version': 0}

This might be part of the warnings module and indicates that there is a warning somewhere which is not printed, but the documentation mentions only a variable __warningregistry__ in the the module warnings .

The documentation explains how from . import foo from . import foo works , and how from bar import * works , but I couldn't find anything about from . import * from . import * . One might expect that all names from __init__.py are loaded into the current name space (as from bla import * would do for bla.py ) but this doesn't seem to be the case and also it doesn't make sense when __name__ == '__main__' (scripts and terminal).

Python 2 behaves more similar to what I had expected:

>>> # 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 is quite illuminative but doesn't answer my question either.

When __main__ is a script or interactive session, . is the __main__ package itself:

$ 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)

This makes from . import * from . import * a noop, with __warningregistry__ added as a side-effect of the import machinery.


Relative imports from __main__ were special-cased by PEP 366 . This introduced __package__ for relative package name lookup, and specifies that __main__. __package__ __main__. __package__ has the special value None .

In addition, the module import spec __main__.__spec__ may be None - namely in an interactive shell or when executing a script.

As it turns out, any module with __package__ = __spec__ = None will treat . as itself:

$ 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)

The __warningregistry__ is added because there is a hidden warning from the missing attributes . It is suppressed by default, but you can see it with 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM