在 Python 中导入模块是否会在本地范围内执行所有模块的导入?


$ python -c 'import urllib.parse; print(urllib.error.HTTPError)'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AttributeError: module 'urllib' has no attribute 'error'

那是预期的。我没有导入urllib.error模块。

$ python -c 'import urllib.request; print(urllib.request.HTTPError)'
<class 'urllib.error.HTTPError'>

也是如此。urllib.request导入urllib.error

from urllib.error import URLError, HTTPError, ContentTooShortError

因此,这些名称可通过 urllib.request.

获得
$ python -c 'import urllib.request; print(urllib.error.HTTPError)'
<class 'urllib.error.HTTPError'>

但不是这个。是什么让我能够通过urllib.error访问HTTPError?我已经阅读了文档,但那里没有线索。

好吧,让我们看看:

import urllib.parse
globals()

您会看到一个项目:

'urllib': <module 'urllib' from 'C:\Users\XXXX\AppData\Local\Programs\Python\Python35\lib\urllib\__init__.py'>

然后,尝试dir(urllib),您会看到:

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'parse']

因此,urllib中有一个parse,但没有requesterror。因为parse不导入它们。

现在让我们转到urllib.request

import urllib.request
globals()

获取项目:

'urllib': <module 'urllib' from 'C:\Users\XXXX\AppData\Local\Programs\Python\Python35\lib\urllib\__init__.py'>

它与import urllib.parse相同。

然后再次尝试dir(urllib)

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'error', 'parse', 'request', 'response']

其中有'error', 'parse', 'request', 'response'。为什么?因为urllib.request导入它们

让我尝试用更多细节来解释它。导入urllib.request首先导入urllib,然后是urllib.request。导入urllib在本地范围中为我们提供了urllib符号,代表已导入的模块。导入urllib.request导入urllib.error。将error符号添加到urllib模块中。和,由于我们有参考urllib ,这使我们能够在导入urllib.request之后访问urllib.error。考虑以下示例:

./main.py

#!/usr/bin/env python
import a.b
print(a.c.c)   # 2
print(d.e.e)   # NameError

./a/b.py

import a.c
import d.e
b = 1

./a/c.py

c = 2

./d/e.py

e = 3

不确定是否是您预期的,但这是设计的。您是否查看urllib/parse.py和urllib/request的来源。来自urllib.error,urllib.parse和urllib.Response的符号。

这就是为什么即使导入不在您自己的源文件中,也可以找到可用的原因。

一个更详细的答案将需要对Python导入机械进行详细说明,并且远远超出了SO答案中的适当情况。请参阅官方文件以进行更深入的解释。

最新更新