Reloading on the fly: was: Re: Python Productivity over C++
Alex
cut_me_out at hotmail.com
Sat Jun 10 10:35:04 EDT 2000
> Could you post an example of designing the main program to reload
> submodules? I'd like to get that working, too, and coming from
> languages where that's impossible, I've a bit of trouble coming up
> with a solution...
I posted something about that recently. I've posted the code again
below. I must admit, I haven't had much occasion to test it yet, as I
haven't been working on anything with complex module dependancies.
Also, if you had many modules, it would probably be a bit slow as it
stands.
import sys, string
from types import ModuleType
class Reloader:
'''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