views:

1609

answers:

5

I often test my module in the Python Interpreter, and when I see an error, I quickly update the .py file. But how do I make it reflect on the Interpreter ? So, far I have been exiting and reentering the Interpreter because re importing the file again is not working for me.

+18  A: 

Use the reload builtin:

http://docs.python.org/library/functions.html#reload

When reload(module) is executed:

  • Python modules’ code is recompiled and the module-level code reexecuted, defining a new set of objects which are bound to names in the module’s dictionary. The init function of extension modules is not called a second time.
  • As with all other objects in Python the old objects are only reclaimed after their reference counts drop to zero.
  • The names in the module namespace are updated to point to any new or changed objects.
  • Other references to the old objects (such as names external to the module) are not rebound to refer to the new objects and must be updated in each namespace where they occur if that is desired.

Example:

# Make a simple function that prints "version 1"
shell1$ echo 'def x(): print "version 1"' > mymodule.py

# Run the module
shell2$ python
>>> import mymodule
>>> mymodule.x()
version 1

# Change mymodule to print "version 2" (without exiting the python REPL)
shell2$ echo 'def x(): print "version 2"' > mymodule.py

# Back in that same python session
>>> reload(mymodule)
<module 'mymodule' from 'mymodule.pyc'>
>>> mymodule.x()
version 2
allyourcode
Note that reload only reloads the specified modules; that module's imports must be individually reloaded, too.
Richard Levasseur
I tried, but it did not work for me. In my case it's a Class FileMyClass.pyclass MyClass: def __init__(self): return 1 def do_some_work(self): work = 2 + 3 print work
Also note that any objects that refer to anything in the module (like an instance whose class is defined in the module) will continue to use the old, pre-reload thing. In general, restarting the interpreter is the cleanest way to go.
Miles
By the way, there is an interesting proposal addressing reload() issues at http://lists.canonical.org/pipermail/kragen-hacks/2002-January/000302.html
dragonfly
+5  A: 

So, far I have been exiting and reentering the Interpreter because re importing the file again is not working for me.

Yes, just saying ‘import’ again gives you the existing copy of the module from sys.modules.

You can say ‘reload(module)’ to update sys.modules and get a new copy of that single module, but if any other modules have a reference to the original module or any object from the original module, they will keep their old references and Very Confusing Things will happen.

So if you've got a module ‘a’, which depends on module ‘b’, and b changes, you have to ‘reload b’ followed by ‘reload a’. If you've got two modules which depend on each other, which is extremely common when those modules are part of the same package, you can't reload them both: if you reload ‘p.a’ it'll get a reference to the old ‘p.b’, and vice versa. The only way to do it is to unload them both at once by deleting their items from sys.modules, before importing them again. This is icky and has some practical pitfalls to do with modules entries being None as a failed-relative-import marker.

And if you've got a module which passes references to its objects to system modules — for example it registers a codec, or adds a warnings handler — you're stuck; you can't reload the system module without confusing the rest of the Python environment.

In summary: for all but the simplest case of one self-contained module being loaded by one standalone script, reload() is very tricky to get right; if, as you imply, you are using a ‘package’, you will probably be better off continuing to cycle the interpreter.

bobince
+2  A: 

See here for a good explanation of how your dependent modules won't be reloaded and the effects that can have:

http://pyunit.sourceforge.net/notes/reloading.html

The way pyunit solved it was to track dependent modules by overriding __import__ then to delete each of them from sys.modules and re-import. They probably could've just reload'ed them, though.

Joe W.
+1  A: 

Basically reload as in allyourcode's asnwer. But it won't change underlying the code of already instantiated object or referenced functions. Extending from his answer:

#Make a simple function that prints "version 1"
shell1$ echo 'def x(): print "version 1"' > mymodule.py

# Run the module
shell2$ python
>>> import mymodule
>>> mymodule.x()
version 1
>>> x = mymodule.x
>>> x()
version 1
>>> x is mymodule.x
True


# Change mymodule to print "version 2" (without exiting the python REPL)
shell2$ echo 'def x(): print "version 2"' > mymodule.py

# Back in that same python session
>>> reload(mymodule)
<module 'mymodule' from 'mymodule.pyc'>
>>> mymodule.x()
version 2
>>> x()
version 1
>>> x is mymodule.x
False
vartec
A: 

Not sure if this does all expected things, but you can do just like that:

>>> del mymodule
>>> import mymodule
dragonfly