tags:

views:

232

answers:

3

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 X from a module Y and reloading on a change, not a module X from a package Y.

+6  A: 

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
I see your point. Would you care to elaborate on any of the other good reasons why it is not a good idea?
cschol
@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
+1 for answer, rich, long comment and mentioning your employer's style guide. :)
cschol
A: 
  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
A: 

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