$ 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
imports urllib.error
:
from urllib.error import URLError, HTTPError, ContentTooShortError
因此名称可通过urllib.request
获得。
$ python -c 'import urllib.request; print(urllib.error.HTTPError)'
<class 'urllib.error.HTTPError'>
但不是这个。是什么让我能够通过HTTPError
访问urllib.error
?我看过the docs,但没有看到任何线索。
答案 0 :(得分:1)
好的,让我们看看:
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']
parse
中有一个urllib
,但不是request
或error
。因为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.error
后访问urllib.request
。请考虑以下示例:
./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
答案 1 :(得分:0)
不确定它是否符合您的预期,但这是设计。你看看urllib / parse.py和urllib / request.py的来源你会看到一个重要的区别:前者只导入re,sys和collections模块,后者(除了其他不相关的模块外)也明确导入来自urllib.error,urllib.parse和urllib.response的符号。
这就是为什么即使导入不在您自己的源文件中也能找到它们的原因。
更详细的答案需要详细描述Python导入机制,远远超出SO答案中的适当范围。请参阅官方文档以获得更深入的解释。