Whenever I run the command on Ubuntu Linux:
python3 -v
I get a verbose output which tells me:
import _frozen_importlib # frozen
import _imp # builtin
import sys # builtin
import '_warnings' # <class '_frozen_importlib.BuiltinImporter'>
import '_thread' # <class '_frozen_importlib.BuiltinImporter'>
import '_weakref' # <class '_frozen_importlib.BuiltinImporter'>
import '_frozen_importlib_external' # <class '_frozen_importlib.FrozenImporter'>
import '_io' # <class '_frozen_importlib.BuiltinImporter'>
And much much more.
However, I see that import sys was executed, yet I still need to manually import sys to use it. Why is this happening?
The short (and inaccurate) version: import foo
does two separate things:
foo
in the current namespaceYou have to "manually import" sys
for the same reason that this doesn't work:
>>> def r():
... import random
... print(random.randint(0, 100))
...
>>> r()
26
>>> random.randint(10, 20)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'random' is not defined
A way to demonstrate that import is nothing magic:
$ cat foo.py
print('foo has been imported')
def fn():
print('fn has been called')
$ python
>>> import importlib
>>> bar = importlib.__import__('foo')
foo has been imported
>>> bar.fn()
fn has been called
The module name works like any other name in Python:
importlib.__import__()
creates a value (a module, in this case) and the =
assigns it to the name.
With a conventional import, import foo
creates a value (the same module) and assigns it to the given name (which just happens to be the same as the module name).
You can verify that a module is only loaded once like this:
$ python
>>> import foo
foo has been imported
>>> import foo
>>>
and you can demonstrate that a module is just another value:
>>> import foo
foo has been imported
>>> foo.fn()
fn has been called
>>> bar = foo
>>> bar.fn()
fn has been called