I know how to use both, but I'm curious why the decision was made to make one a statement and the other a function.
-
Never thought about that. – linusg Apr 25 '16 at 13:24
-
because the `import` statement benefits from alternate syntax like `from __ import __ as __` where as `reload` only ever needs the module object to re use it's loader. – Tadhg McDonald-Jensen Apr 25 '16 at 13:27
-
`import` is used to import modules, `reload()` can also load certain parts of a module. – linusg Apr 25 '16 at 13:28
-
@cricket_007 if it was a statement it would just as easily be written `reload random #name` as appose to `reload(random) #module object` – Tadhg McDonald-Jensen Apr 25 '16 at 13:29
-
2I'd possibly check when the `reload` function was added. Since it's such a common name, I figure it would break a lot of existing code if it suddenly became a keyword. – Vincent Savard Apr 25 '16 at 13:34
-
Reolad function because call statement with changes ! import do nothing ! – dsgdfg Apr 25 '16 at 13:39
1 Answers
First of all you can import using a function, from importlib's documentation:
The
__import__()
function
Theimport
statement is syntactic sugar for this function.
for instance both of these statements are equivalent:
from random import randint as random_int
random_int = __import__("random").randint
Reload only makes sense as an operation applied to a module object where as importing benefits from alternative syntax to avoid repetition, especially if you are importing several names from a module
from foo import a,b,c
# vs
a = __import__("foo").a; b = __import__("foo").b; c = __import__("foo").c
# or maybe:
_foo = __import__("foo")
a,b,c = _foo.a, _foo.b, _foo.c
del _foo
It is also highly desirable for the mechanism to load submodules to run on the same step as the import and not when an attribute is attempted to be loaded, so this is also much easier with the syntax sugar:
# from http import HTTPStatus
HTTPStatus = __import__("http").HTTPStatus # works
# try to load a submodule, but only reference the submodule on attribute lookup not as part of the import
server = __import__("http").server
# ^ AttributeError: module 'http' has no attribute 'server'
from http import server # this works because the import mechanism tries to load submodule
assert not hasattr(http, "client") # is another submodule that is not loaded automatically
thingy = __import__("http.client")
# what would you expect `thingy` to be?
# remember that doing `import http.client` loads the submodule but only
# puts `http` in the global scope so you still refer to the submodule as
# `http.client` so here thingy is actually `http`
assert thingy is __import__("http") # passes
As for reload, if it was a statement I can imagine a lot of beginner programmers making this mistake:
from random import randint as r1
reload random # reload(__import__("random"))
from random import randint as r2
assert r1 is r2, "reloading a module only updates the namespace of the module itself, not any directly imported members"
# ^ will fail
the reload
function can't possibly update fields that were imported by name, only updating the fields on the module object itself. related to this answer

- 20,699
- 5
- 35
- 59