Confused about "reload"

Thomas Wouters thomas at xs4all.net
Fri May 19 13:58:57 EDT 2000


On Fri, May 19, 2000 at 01:29:13PM -0400, blues-l at cyberus.ca wrote:

> class tryit:
>  def __init__(self,mess):
>   self.mess=mess
>  def printit(self):
>   print "this is", self.mess
> 
> .. I can "import tester"and reload(tester)
> and I can get an updated "tryit"
> but if I "from tester import *"
> I can't get a reload of "tryit" to happen.
> What does the reloadline look like in that case???

'from tester import *' does not do what you think it does. What it does is
copy references from the 'tester' namespace to the current namespace. If the
objects referred to are mutable, they can change and you will see the
change. But if the references in the original namespace are *changed* (like
reload() might do, if the code has changed), the original references are
removed, and new references are put in place. But your local copies of those
references are still pointing to the old objects, not the new ones.

So if you use reload(), you'll have to re-bind the local names to the names
from the module, either by hand, or by doing another 'from tester import *'
-- but if you did the first import at the global level, this can be tricky
;) The best thing is not to use 'from tester import *'. If you want to use a
'from x import ..' construct, list the names you wish to import, and when
you reload, reload those names specifically:

import tester
tryit, doit, forceit = tester.tryit, tester.doit, tester.forceit
...

   if self.should_reload():
	global tryit, doit, forceit
	reload(tester)
	tryit, doit, forceit = tester.tryit, tester.doit, tester.forceit

But this is really hackish, particularly because you need the module object,
not the name, to reload() it, so you have to use 'import tester' anyway.
Also the binding of the global variables to the (possibly) new entries of
tryit, doit and forceit is tricky -- if you wish to import more variables,
you have to change code at 3 (or more) places. It really is best to use
'import tester' and use 'tester.tryit' all the time.

A note of warning, if you subclass tester.tryit in another module, then
change tester and reload(), your subclass will actually be a subclass of the
old tryit. It will not get changed... You can do this by hand, by setting
the __bases__ attribute, but that's getting hackish again. It's probably
easier (and better, when you call the parents __init__ class and such) to
re-define your subclass and re-create any instances of that class, if you
want them to inherit any new functionality.

-- 
Thomas Wouters <thomas at xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!




More information about the Python-list mailing list