135

In Python, once I have imported a module X in an interpreter session using import X, and the module changes on the outside, I can reload the module with reload(X). The changes then become available in my interpreter session.

I am wondering if this also possible when I import a component Y from module X using from X import Y.

The statement reload Y does not work, since Y is not a module itself, but only a component (in this case a class) inside of a module.

Is it possible at all to reload individual components of a module without leaving the interpreter session (or importing the entire module)?

EDIT:

For clarification, the question is about importing a class or function Y from a module X and reloading on a change, not a module Y from a package X.

CharlesB
  • 86,532
  • 28
  • 194
  • 218
cschol
  • 12,799
  • 11
  • 66
  • 80
  • I believe there is a contradiction in this question: "`... possible ... import a component Y from module X`" vs "`question is ... importing a class or function X from a module Y`". I'm adding an edit to that effect. – Catskul Jul 30 '12 at 14:50
  • 1
    it appears that the marked answer does not actually answer the question, I believe mine does. Can you update/comment? – Catskul Mar 16 '14 at 10:03

9 Answers9

140

Answer

From my tests, the marked answer, which suggests a simple reload(X), does not work.

From what I can tell the correct answer is:

from importlib import reload # python 2.7 does not require this
import X
reload( X )
from X import Y

Test

My test was the following (Python 2.6.5 + bpython 0.9.5.2)

X.py:

def Y():
    print "Test 1"

bpython:

>>> from X import Y
>>> print Y()
Test 1
>>> # Edit X.py to say "Test 2"
>>> print Y()
Test 1
>>> reload( X )  # doesn't work because X not imported yet
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'X' is not defined
>>> import X
>>> print Y()
Test 1
>>> print X.Y()
Test 1
>>> reload( X ) # No effect on previous "from" statements
>>> print Y()
Test 1
>>> print X.Y() # first one that indicates refresh
Test 2
>>> from X import Y
>>> print Y()
Test 2 
>>> # Finally get what we were after
Catskul
  • 17,916
  • 15
  • 84
  • 113
  • 4
    Wow. I found this really handy. Thanks! I use this as one liner now: import X; reload( X ); from X import Y – otterb Apr 23 '14 at 22:26
  • 2
    This is a better answer than the accepted one. It's fair to warn people, but everyone's use case is different. In some cases it really is helpful to reload a class, eg when you're using the python console and want to load changes to your code without losing your session. – nicb Feb 12 '17 at 01:11
  • 2
    This doesn't seem to work always. I have a module `Foo` which has an `__init__.py` that fetches a submodule... I'll post an answer as a counterexample. – Jason S Oct 17 '17 at 22:32
  • 1
    Python 3 one liner now: import importlib;import X; importlib.reload( X ); from X import Y – Wayne Sep 14 '18 at 15:59
  • well in this answer you must now import x right? – JobHunter69 May 02 '21 at 05:51
  • it is ugly but it is the only thing that I know of that gets the job done...thanks. – Rayhunter Jan 15 '22 at 12:00
55

If Y is a module (and X a package) reload(Y) will be fine -- otherwise, you'll see why good Python style guides (such as my employer's) say to never import anything except a module (this is one out of many great reasons -- yet people still keep importing functions and classes directly, no matter how much I explain that it's not a good idea;-).

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • 3
    I see your point. Would you care to elaborate on any of the other good reasons why it is not a good idea? – cschol Nov 16 '09 at 03:55
  • 9
    @cschol: Zen of Python, last verse (`import this` from interactive prompt to see the Zen of Python); and all the reasons _why_ namespaces are a honking great idea (immediate local visual clues that the name's being looked up, ease of mocking/injecting in tests, ability to reload, ability for a module to change flexibly by redefining some entries, predictable and controllable behavior on serialization and recovery of your data [[e.g. by pickling and unpickling]], and so on, and so forth -- a SO comment is hardly long enough to do justice to this rich, long argument!!!-) – Alex Martelli Nov 16 '09 at 05:20
  • +1 for answer, rich, long comment and mentioning your employer's style guide. :) – cschol Nov 17 '09 at 01:41
  • I'm not sure if it might be because of the contradiction confusion in the OP, but this appears to be incorrect. – Catskul Jul 30 '12 at 15:07
  • 4
    note that in Python 3, reload is no longer in the default namespace but has been moved to the `importlib` package. `importlib.reload(Y)` https://docs.python.org/3.4/library/importlib.html?highlight=reload#functions see also http://stackoverflow.com/questions/961162/reloading-module-giving-error-reload-is-not-defined – flies Dec 13 '14 at 21:58
  • @AlexMartelli Does this guideline basically mean "never use `from`"? – ThorSummoner Oct 22 '15 at 17:48
  • 5
    @ThorSummoner, absolutely not -- it means "always import MODULES", so "from my.package import mymodule" is absolutely fine and indeed preferred -- just, never import classes, functions, etc -- always, only, ever *modules*. – Alex Martelli Oct 23 '15 at 01:23
  • 4
    Downvote. Why? This is not the right answer. The right answer was given by Catskul on Jul 30 '12 at 15:04. – meh Dec 14 '17 at 01:59
  • the problem is I learnt from answers like this https://stackoverflow.com/a/21995949/2262424 and seems like I was not the only one... shall I rather proceed with https://stackoverflow.com/a/4383597/2262424 ? – gevra Mar 29 '18 at 21:27
29
from modulename import func

import importlib, sys
importlib.reload(sys.modules['modulename'])
from modulename import func
mirek
  • 1,140
  • 11
  • 10
  • 1
    This is the best way imo because you might not remember exactly how it was imported – benathon Jul 16 '15 at 06:34
  • 2
    That's the only working solution to the original question, and has too few votes! – CharlesB Feb 28 '20 at 11:04
  • In python2 do the same but without importing of the importlib - just call reload(), which is a standalone command in python2. – mirek Dec 07 '20 at 17:35
6

First off, you shouldn't be using reload at all, if you can avoid it. But let's assume you have your reasons (i.e. debugging inside IDLE).

Reloading the library won't get the names back into the module's namespace. To do this, just reassign the variables:

f = open('zoo.py', 'w')
f.write("snakes = ['viper','anaconda']\n")
f.close()

from zoo import snakes
print snakes

f = open('zoo.py', 'w')
f.write("snakes = ['black-adder','boa constrictor']\n")
f.close()

import zoo
reload(zoo)
snakes = zoo.snakes # the variable 'snakes' is now reloaded

print snakes

You could do this a few other ways. You could automate the process by searching through the local namespace, and reassigning anything that was from the module in question, but I think we are being evil enough.

wisty
  • 6,981
  • 1
  • 30
  • 29
5

If you're working in a jupyter environment, and you already have from module import function can use the magic function, autoreload by

%load_ext autoreload
%autoreload
from module import function

The introduction of the autoreload in IPython is given here.

Max Wong
  • 694
  • 10
  • 18
4

If you want to do this:

from mymodule import myobject

Do this instead:

import mymodule
myobject=mymodule.myobject

You can now use myobject in the same way as you were planning (without the tiresome unreadable mymodule references everywhere).

If you're working interactively and want to reload myobject from mymodule you now can using:

reload(mymodule)
myobject=mymodule.myobject
Chris Fryer
  • 726
  • 3
  • 7
3

assuming you used from X import Y, you have two options:

reload(sys.modules['X'])
reload(sys.modules[__name__]) # or explicitly name your module

or

Y=reload(sys.modules['X']).Y

few considerations:

A. if the import scope is not module-wide (e,g: import in a function) - you must use the second version.

B. if Y is imported into X from another module (Z) - you must reload Z, than reload X and than reload your module, even reloading all your modules (e,g: using [ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ]) might reload X before reloading Z - and than not refresh the value of Y.

Ohad Cohen
  • 5,756
  • 3
  • 39
  • 36
1
  1. reload() module X,
  2. reload() module importing Y from X.

Note that reloading won't change already created objects bound in other namespaces (even if you follow style guide from Alex).

Denis Otkidach
  • 32,032
  • 8
  • 79
  • 100
1

Just to follow up on AlexMartelli's and Catskul's answers, there are some really simple but nasty cases that appear to confound reload, at least in Python 2.

Suppose I have the following source tree:

- foo
  - __init__.py
  - bar.py

with the following content:

init.py:

from bar import Bar, Quux

bar.py:

print "Loading bar"

class Bar(object):
  @property
  def x(self):
     return 42

class Quux(Bar):
  object_count = 0
  def __init__(self):
     self.count = self.object_count
     self.__class__.object_count += 1
  @property
  def x(self):
     return super(Quux,self).x + 1
  def __repr__(self):
     return 'Quux[%d, x=%d]' % (self.count, self.x)

This works just fine without using reload:

>>> from foo import Quux
Loading bar
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> Quux()
Quux[2, x=43]

But try to reload and it either has no effect or corrupts things:

>>> import foo
Loading bar
>>> from foo import Quux
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> reload(foo)
<module 'foo' from 'foo\__init__.pyc'>
>>> Quux()
Quux[2, x=43]
>>> from foo import Quux
>>> Quux()
Quux[3, x=43]
>>> reload(foo.bar)
Loading bar
<module 'foo.bar' from 'foo\bar.pyc'>
>>> Quux()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "foo\bar.py", line 17, in __repr__
    return 'Quux[%d, x=%d]' % (self.count, self.x)
  File "foo\bar.py", line 15, in x
    return super(Quux,self).x + 1
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> Quux().count
5
>>> Quux().count
6
>>> Quux = foo.bar.Quux
>>> Quux()
Quux[0, x=43]
>>> foo.Quux()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "foo\bar.py", line 17, in __repr__
    return 'Quux[%d, x=%d]' % (self.count, self.x)
  File "foo\bar.py", line 15, in x
    return super(Quux,self).x + 1
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> foo.Quux().count
8

The only way I could ensure the bar submodule was reloaded was to reload(foo.bar); the only way I access the reloaded Quux class is to reach in and grab it from the reloaded sub module; but the foo module itself kept holding onto the original Quux class object, presumably because it uses from bar import Bar, Quux (rather than import bar followed by Quux = bar.Quux); furthermore the Quux class got out of sync with itself, which is just bizarre.

Jason S
  • 184,598
  • 164
  • 608
  • 970