Automatic reload()?
Alex
cut_me_out at hotmail.com
Sat Jun 3 19:26:06 EDT 2000
import sys, string
from types import ModuleType
class Reloader:
'''
This is so complex that I've probably added more problems than I've
solved. But anyway, here is my attempt at something that figures
out an appropriate reloading order for you. You create an instance
of the class, call it 'rr', before you have imported any of the
modules you'll be wanting to reload (the .pythonrc file would be a
good place.) Then when you wish to reload the modules in a given
namespace, you run the command
exec (rr (globals ()))
In my case, the namespace would usually be __main__, so this would
just go at the top of the script I'm currently working on in
emacs.
Alex.
'''
def __init__ (self):
self.keepem = sys.modules.copy ()
def get_new_modules (self):
modules = {}
for i, m in sys.modules.items():
if (not self.keepem.has_key (i)) and \
(type(m) == ModuleType):
modules[i] = m
return modules
def clear_sys_modules (self):
for i in self.modules.keys ():
if sys.modules.has_key (i):
del sys.modules[i]
def get_dependancies (self, module_name):
self.clear_sys_modules ()
exec 'import ' + module_name
new_modules = self.get_new_modules ()
del new_modules[module_name]
return new_modules
def determine_reloads (self):
self.return_commands = []
while self.dependancies:
for i, deps in self.dependancies.items ():
if not deps:
break
else:
raise 'Cyclic dependancy(?)'
exec 'import ' + i
reload (eval (i))
if self.namespace.has_key (i) and \
(self.namespace[i] == self.modules[i]):
self.return_commands.append (
'import %s; reload (%s)' % (i, i))
del self.dependancies[i]
for deps in self.dependancies.values ():
while deps.count (i):
deps.remove (i)
def __call__ (self, namespace):
self.namespace = namespace
self.modules = self.get_new_modules ()
self.dependancies = {}
for module_name in self.modules.keys ():
deps = self.get_dependancies (module_name).keys ()
self.dependancies[module_name] = deps
self.determine_reloads ()
return string.join (self.return_commands, ';')
rr = Reloader ()
if __name__ == '__main__':
'''This is a test script, intended to be run with two modules, B.py
and C.py somewhere in the directories in sys.path. Their contents
should be
B.py:
######################################################################
import C
class B (C.C):
def __init__ (self):
C.C.__init__ (self)
C.py:
######################################################################
class C:
def __init__ (self):
pass
'''
import B, C
bid = id (B.B)
cid = id (C.C)
exec (rr (globals ()))
assert (bid != id (B.B)) and (cid != id (C.C))
t = B.B ()
More information about the Python-list
mailing list