The urllib package serves as a namespace only. There are other modules under urllib like request and parse.
For optimization importing urllib doesn't import other modules under it. Because doing so would consume processor cycles and memory, but people may not need those other modules.
Individual modules under urllib must be imported separately depending on the needs.
Try these, the first one fails but the second succeeds because when flask is imported flask itself imports urllib.parse.
python3 -c 'import urllib, sys;print(sys.modules["urllib.parse"])'
python3 -c 'import flask, sys;print(sys.modules["urllib.parse"])'
Answer from Nizam Mohamed on Stack OverflowThe urllib package serves as a namespace only. There are other modules under urllib like request and parse.
For optimization importing urllib doesn't import other modules under it. Because doing so would consume processor cycles and memory, but people may not need those other modules.
Individual modules under urllib must be imported separately depending on the needs.
Try these, the first one fails but the second succeeds because when flask is imported flask itself imports urllib.parse.
python3 -c 'import urllib, sys;print(sys.modules["urllib.parse"])'
python3 -c 'import flask, sys;print(sys.modules["urllib.parse"])'
For code 1 to work you need to import the urllib.parse module, not the function quote. This way you can refer to the quote function with full module qualifier. With this approach you can use any function defined in the parse module:
import urllib.parse
s = urllib.parse.quote('"')
print(s)
code 2 works, because you import only the parse function and refer to it without module qualifier, since it is not imported in the context of the module. With this approach you can use only the explicitly imported function from the parse module.
code 3 works, because flask imports implicitly the urllib.parse module. The parse module becomes available in the urllib module context. Once you import urllib, urllib.parse becomes readily available and you can use it as in code 1
Rhino 9 WIP Python 3 Error: module 'urllib' has no attribute 'parse'
AttributeError: 'module' object has no attribute 'parse'
AttributeError: module 'urllib' has no attribute 'error'
import urllib.parse fails when Python run from command line - Stack Overflow
When you run import urllib, it creates the module object of the urllib module (which is actually a package) without importing its submodules (parse, request etc.).
You need the parent module object (urllib) to be in your namespace if you want to access its submodule using attribute access. In addition to that, that submodule must already be loaded (imported). From the documentation:
if package
spamhas a submodulefoo, after importingspam.foo,spamwill have an attributefoowhich is bound to the submodule. [...] The invariant holding is that if you havesys.modules['spam']andsys.modules['spam.foo'](as you would after the above import), the latter must appear as thefooattribute of the former.
There is only one instance of each module, thus any changes made to the urllib module object (stored in sys.modules['urllib']) get reflected everywhere.
You don't import urllib.parse, but IPython does. To prove this I'm going to create a startup file:
import urllib
print('Running the startup file: ', end='')
try:
# After importing 'urllib.parse' ANYWHERE,
# 'urllib' will have the 'parse' attribute.
# You could also do "import sys; sys.modules['urllib'].parse"
urllib.parse
except AttributeError:
print("urllib.parse hasn't been imported yet")
else:
print('urllib.parse has already been imported')
print('Exiting the startup file.')
and launch ipython
vaultah@base:~$ ipython
Running urllib/parse.py
Running the startup file: urllib.parse has already been imported
Exiting the startup file.
Python 3.6.0a0 (default:089146b8ccc6, Sep 25 2015, 14:16:56)
Type "copyright", "credits" or "license" for more information.
IPython 4.0.0 -- An enhanced Interactive Python.
It is the side effect of importing pydoc during the startup of IPython (which ipython is /usr/local/bin/ipython):
/usr/local/bin/ipython, line 7:
from IPython import start_ipython
/usr/local/lib/python3.6/site-packages/IPython/__init__.py, line 47:
from .core.application import Application
/usr/local/lib/python3.6/site-packages/IPython/core/application.py, line 24:
from IPython.core import release, crashhandler
/usr/local/lib/python3.6/site-packages/IPython/core/crashhandler.py, line 28:
from IPython.core import ultratb
/usr/local/lib/python3.6/site-packages/IPython/core/ultratb.py, line 90:
import pydoc
/usr/local/lib/python3.6/pydoc.py, line 68:
import urllib.parse
This explains why the below code fails - you only import urllib and nothing seems to import urllib.parse:
$ python -c 'import urllib; print(urllib.parse)'
On the other hand, the following command works because datetime.datetime is not a module. It's a class that gets imported during import datetime.
$ python -c 'import datetime; print(datetime.datetime)'
urllib.parse is available from Python 3 onwards. I think you might need to import urllib.parse, not import urllib. Not sure if (when) submodule import is implicit.
I would guess IPython imports urllib.parse on startup and that is why it is available.
parse is a module not an attribute:
Python 3.4.2 (default, Oct 15 2014, 22:01:37)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib
>>> urllib.parse
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'parse'
>>> import urllib.parse
>>> urllib.parse
<module 'urllib.parse' from '/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/parse.py'>