None of these answers did the job properly for me, so I put together something very messy and very non-pythonic to do the job myself. Even after running it for several weeks, I am finding small issues and fixing them. One issue will be if your PWD/CWD changes.
Warning this is very ugly code. Perhaps someone will make it pretty, but it does work.
Not only does it create a refresh() function that properly reloads your script in a manner such that any Exceptions will properly display, but it creates refresh_<scriptname> functions for previously loaded scripts just-in-case you need to reload those.
Next I would probably add a require portion, so that scripts can reload other scripts -- but I'm not trying to make node.js here.
First, the "one-liner" that you need to insert in any script you want to refresh.
with open(os.path.dirname(__file__) + os.sep + 'refresh.py', 'r') as f: \ exec(compile(f.read().replace('__BASE__', \ os.path.basename(__file__).replace('.py', '')).replace('__FILE__', \ __file__), __file__, 'exec'))
And second, the actual refresh function which should be saved to refresh.py in the same directory. (See, room for improvement already).
def refresh(filepath = __file__, _globals = None, _locals = None): print("Reading {}...".format(filepath)) if _globals is None: _globals = globals() _globals.update({ "__file__": filepath, "__name__": "__main__", }) with open(filepath, 'rb') as file: exec(compile(file.read(), filepath, 'exec'), _globals, _locals) def refresh___BASE__(): refresh("__FILE__")
Tested with Python 2.7 and 3.