Online Modification of Python Code

Bengt Richter bokr at oz.net
Mon Sep 5 23:44:23 EDT 2005


On Mon, 05 Sep 2005 11:53:09 +0200, "Diez B. Roggisch" <deets at nospam.web.de> wrote:

>> 
>> I seem to recall a post by Diez Roggish that reload() doesn't always
>> work as it should. Any news on this? At least im my preliminary test it
>> works.
>
>Read the docs on reload:
>
>http://www.python.org/doc/current/lib/built-in-funcs.html
>
>"""
>
>If a module is syntactically correct but its initialization fails,  the 
>first import statement for it does not bind its name  locally, but does 
>store a (partially initialized) module object in  sys.modules. To reload 
>the module you must first  import it again (this will bind the name to 
>the partially  initialized module object) before you can reload() it.
>
>When a module is reloaded, its dictionary (containing the module's 
>global variables) is retained. Redefinitions of names will override  the 
>old definitions, so this is generally not a problem. If the new  version 
>of a module does not define a name that was defined by the  old version, 
>the old definition remains. This feature can be used  to the module's 
>advantage if it maintains a global table or cache of  objects -- with a 
>try statement it can test for the  table's presence and skip its 
>initialization if desired:
>
>
>try:
>     cache
>except NameError:
>     cache = {}
>
>
>It is legal though generally not very useful to reload built-in or 
>dynamically loaded modules, except for sys,  __main__ and __builtin__. 
>In  many cases, however, extension modules are not designed to be 
>initialized more than once, and may fail in arbitrary ways when  reloaded.
>
>If a module imports objects from another module using from  ... import 
>..., calling reload() for  the other module does not redefine the 
>objects imported from it --  one way around this is to re-execute the 
>from statement,  another is to use import and qualified names 
>(module.name) instead.
>
>If a module instantiates instances of a class, reloading the module 
>that defines the class does not affect the method definitions of the 
>instances -- they continue to use the old class definition. The  same is 
>true for derived classes.
>"""
>
>So - expect strange things to happen, sometimes.
>
>I personally _never_ felt the need for reload - after all, writing more 
>than totally trivial crap on the commandline justifies a small 
>testscript - which I then just execute on the commandline.
>
>Diez
What about something on the pattern of (untested!)

    import algomodule # first time

    def algoreload():
	algosource = algomodule.__file__.replace('.pyc','py')
        algomodule.__dict__.clear()
	try:
	    execfile(algosource, algomodule.__dict__)
            algomodule.__file__ = algosource
            return 'ok'
        except Exception, e:
            return '%s: %s -- couldn't execfile %r' %(e.__class__.__name__, e, algosource)

    while True:
        cmd = raw_input('cmd > ').strip()
        if cmd == 'reload': print algoreload()
        elif cmd == 'exit': raise SystemExit('ok, exiting ...')
        elif cmd == 'edit': print os.popen('notepad.exe '+algomodule.__file__.replace('.pyc','py')).read() or 'ok'
        else:
            cmd = cmd.split()
            args = map(float, cmd[1:])
            print getattr(algomodule, cmd[0], (lambda name, *ign: 'No such function: %r'%name).__get__(cmd[0], str))(*args)

this would (theoretically ;-) let you type commands like
       sqrt 9
and have alogomodule.sqrt called with float('9'), and then
       edit
and edit the module source in notepad, and then
       sqrt 16
and have the new function called, etc.

The cmd module will let you set up something fancier than above, and obviously you don't have to run notepad ;-)
       
Regards,
Bengt Richter



More information about the Python-list mailing list