How to reload python module imported using `from module import *`

31,773

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
Share:
31,773
murftown
Author by

murftown

Updated on September 23, 2020

Comments

  • murftown
    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 no whatever_module to refer to when I use reload(). Are you guys gonna yell at me for throwing a whole module into the global namespace? :)

  • murftown
    murftown about 13 years
    it's useful in interactive mode though, i am always updating my module and then having to get out and back into python.
  • murftown
    murftown about 13 years
    that's also why i use import * from ___, is just for interactive mode so i don't have to type so much
  • Allen
    Allen about 13 years
    if you use python -i foo.py, you can have python run all your setup code before it gives you a prompt. (and instead of from somepackage.foo import *, why not use from somepackage import foo as f then refer to f.yourObjects, etc?
  • murftown
    murftown about 13 years
    ahh, 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
    Jareth Holt over 8 years
    I have a key question on this point. (5 years late.) If I use import module as mod to avoid from module import *, how do I reload module as mod?
  • Junier
    Junier almost 8 years
    @JarethHolt, you've probably figured this out by now, but just do reload(mod)
  • Bruno Feroleto
    Bruno Feroleto almost 6 years
    Actually, you can officially use from math import * (mostly because mathematical functions have well-known names).
  • Bruno Feroleto
    Bruno Feroleto almost 6 years
    This typically adds symbol X to the namespace, so it is a bit cleaner to respect X not being in the namespace, by doing instead reload(sys.modules["X"]). Granted, this may required adding sys to the namespace, but it is such a common module that this should not shadow anything (whereas X might be shadowed by the added import X).
  • Duccio A
    Duccio A about 5 years
    In case you import a module with an alias, use the alias in reload. For example for import XX as X use reload(X)
  • johnnyheineken
    johnnyheineken almost 5 years
    this comment does not answer the original question
  • murftown
    murftown almost 5 years
    Nice! I like that solution. Thanks for sharing!
  • nocibambi
    nocibambi about 3 years
    This does not seem to work when I have imported an object from a module of a package (from package.module import object).