Re: reload from ( was Python FAQ ... )

Guido.van.Rossum@cwi.nl
Thu, 18 Nov 1993 13:25:10 +0100

> On Nov 17, 11:05, tnb2d@henson.cs.virginia.edu wrote:
> > If I want to get at changes I make to a module I've *import*ed
> > without having to quit the interpreter I can use the reload(module)
> > call, correct? But if I've *import*ed functions and data *from* the
> > module, and not actually *import*ed the module itself this reloading
> > doesn't work. I can't re-*import* parts of a module. Why not? I
> > understand the desire for caching modules and appreciate it MOST of
> > the time, but sometimes I don't want the cached values! There is a
> > way provided to defeat that cache (reload) for *import*ed modules when
> > I want/need to. How hard would it be to provide a 'from module
> > re-import *' call that would defeat the cache and go back to disk for
> > these items as well?

Steven Majewski, who is usually as much of a Python expert as I am,
replies:

> There is a non-obvious, kludgey sort of way to do this. Try:
>
> >>>import sys,posix
> >>>from xxx import *
> >>>posix.system( 'jove xxx.py' )
>
> [ edit xxx.py ... ]
>
> >>>reload( sys.modules['xxx'] )

Actually, there's a flaw in this method. Suppose module xxx defines a
function yyy():

>>> from xxx import *
>>> yyy()
<output from old version of yyy>
[[ edit definitionm of yyy() in xxx.py ]]
>>> import sys
>>> reload(sys.modules['xx'])
>>> yyy()
<output from old version of yyy>
>>> # What has happened ?????????!!!!!!!

What has happened is that the "from xxx import *" has bound the name
yyy in the current (__main__) module to the object bound to the same
name in the module xxx. After the "reload(...)", the name yyy in
module xxx has been bound to a different object, but the name binding
in __main__ hasn't changed! This can be rectified by repeating the
"from xxx import *" command; it will redo all the name bindings.

Actually, I would recommend to write "import xxx" and then
"reload(xxx)" instead of using sys.modules. If there's a name
conflict, e.g. module xxx defines an object xxx, repeating the "from
xxx import *" statement after the reload() call would override it
(from this you can learn, if you didn't know already, that name
bindings are dynamic in Python :-). To have the minimum overall
impact on the name space of __main__, you could add "del xxx",
so the whole idiom would be:

>>> # to reload "from xxx import *" do this:
>>> import xxx
>>> reload(xxx)
>>> del xxx
>>> from xxx import *
>>> # now test out the new version

Steve then proceeds:

> I suppose the elegant way would be to make 'reload' a
> keyword like 'import', rather than a function. It doesn't
> need a from ( demonstrated by the fact that the reload(sys.
> modules[]) above DOESN'T put xxx into the namespace. Try
> dir() after the reload. ) The problem is that since "xxx"
> isn't in the namespace, the expression reload(xxx) doesn't
> have "xxx" defined. import/def/class are statements that
> create new names in the current namespace.
>
> [ But since I suspect that most uses of reload are with
> interactive use and editing, I don't think there is
> a real need to add another keyword. ]

Agreed -- for the very occasional use that reload() finds I don't
think the addition of a new keyword to the language is warranted. New
keywords have much more impact than new built-in functions since they
can break existing programs that happen to use the keyword as a local
variable. I wonder if instead of a reload and a reload-from
statement, we actually aren't in search for an "options" part of
import statements (all flavors). If it's done right this could also
be used to specify an alternate search path or file to load from.

--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>