I haven't been very pleased with any of these options because they all require significant changes to my existing code to implement properly. In my search for the ultimate reload function, I eventually came up with a system that works very well for my application:
- Look through the entire set of imported modules and reload anything that has a new .py file available
- For every function and class method in the module, update the __code__ to point to the new function's __code__
- For every class, find all instances of the class and set __class__ to the new version. (it does not require extra work to track instances; just use gc.get_referrers to find them)
This works well with my existing applications, but there are a few situations where it won't work. If I make changes to the __init__ function of any class, or otherwise expect the internal state of an instance to be changed, I will have to re-create the instances manually (This is generally true of all languages I can think of; there is no general way to automatically re-initialize the state of the program). Additionally, any explicit references to objects in the module other than classes and functions (references to lists, for example) will still point to the old objects. I can't think of a clever way around this, but it can be avoided easily: avoid using "from ... import ..." at all costs. If you are always forced to refer to the module when accessing its objects, then you automatically get the new versions when the module is reloaded.
Without further delay, the magic reloadAll function: http://luke.campagnola.me/code/downloads/reload.py
Leave a comment if you find a bug or have suggestions.