How to reload python module imported using `from module import *`
Solution 1
I agree with the "don't do this generally" consensus, but...
The correct answer is:
import X
reload(X)
from X import Y # or * for that matter
Solution 2
Never use import *
; it destroys readability.
Also, be aware that reloading modules is almost never useful. You can't predict what state your program will end up in after reloading a module, so it's a great way to get incomprehensible, unreproduceable bugs.
Solution 3
A cleaner answer is a mix of Catskul's good answer and Ohad Cohen's use of sys.module
and direct redefinition:
import sys
Y = reload(sys.module["X"]).Y # reload() returns the new module
In fact, doing import X
creates a new symbol (X
) that might be redefined in the code that follows, which is unnecessary (whereas sys
is a common module, so this should not happen).
The interesting point here is that from X import Y
does not add X
to the namespace, but adds module X
to the list of known modules (sys.modules
), which allows the module to be reloaded (and its new contents accessed).
More generally, if multiple imported symbols need to be updated, it is then more convenient to import them like this:
import sys
reload(sys.module["X"]) # No X symbol created!
from X import Y, Z, T
Solution 4
A
from module import *
takes all “exported” objects from module
and binds them to module-level (or whatever-your-scope-was-level) names. You can reload the module as:
reload(sys.modules['module'])
but that won't do you any good: the whatever-your-scope-was-level names still point at the old objects.
Solution 5
I've found another way to deal with reloading a module when importing like:
from directory.module import my_func
It's nice to know how do modules are being imported generally.
The module is searched in sys.modules
dictionary. If it already exists in sys.modules - the module will not be imported again.
So if we would like to reload our module, we can just remove it from sys.modules and import again:
import sys
from directory.module import my_func
my_func('spam')
# output: 'spam'
# here I have edited my_func in module.py
my_func('spam') # same result as above
#output: 'spam'
del sys.modules[my_func.__module__]
from directory.module import my_func
my_func('spam') # new result
#output: 'spam spam spam spam spam'
If You would like to get reloaded module when running whole script, you could use exception handler:
try:
del sys.modules[my_func.__module__]
except NameError as e:
print("""Can't remove module that haven't been imported.
Error: {}""".format(e))
from utils.module import my_func
..........
# code of the script here
murftown
Updated on September 23, 2020Comments
-
murftown almost 4 years
I saw in this useful Q&A that one can use
reload(whatever_module)
or, in Python 3,imp.reload(whatever_module)
.My question is, what if I had said
from whatever_module import *
to import? Then I have nowhatever_module
to refer to when I usereload()
. Are you guys gonna yell at me for throwing a whole module into the global namespace? :) -
murftown about 13 yearsit's useful in interactive mode though, i am always updating my module and then having to get out and back into python.
-
murftown about 13 yearsthat's also why i use import * from ___, is just for interactive mode so i don't have to type so much
-
Allen about 13 yearsif you use
python -i foo.py
, you can have python run all your setup code before it gives you a prompt. (and instead offrom somepackage.foo import *
, why not usefrom somepackage import foo as f
then refer tof.yourObjects
, etc? -
murftown about 13 yearsahh, but i still can't do from somepackage import * as whatever (at least in my python 3)...i know none of u want me to be able to do this anyway! ;)
-
Jareth Holt over 8 yearsI have a key question on this point. (5 years late.) If I use
import module as mod
to avoidfrom module import *
, how do I reloadmodule
asmod
? -
Junier almost 8 years@JarethHolt, you've probably figured this out by now, but just do
reload(mod)
-
Bruno Feroleto almost 6 yearsActually, you can officially use
from math import *
(mostly because mathematical functions have well-known names). -
Bruno Feroleto almost 6 yearsThis typically adds symbol
X
to the namespace, so it is a bit cleaner to respectX
not being in the namespace, by doing insteadreload(sys.modules["X"])
. Granted, this may required addingsys
to the namespace, but it is such a common module that this should not shadow anything (whereasX
might be shadowed by the addedimport X
). -
Duccio A about 5 yearsIn case you import a module with an alias, use the alias in
reload
. For example forimport XX as X
usereload(X)
-
johnnyheineken almost 5 yearsthis comment does not answer the original question
-
murftown almost 5 yearsNice! I like that solution. Thanks for sharing!
-
nocibambi about 3 yearsThis does not seem to work when I have imported an object from a module of a package (
from package.module import object
).