On Fri, 2010-07-09 at 15:58 +0000, Steven D'Aprano wrote:
> On Fri, 09 Jul 2010 15:02:25 +0200, Frederic Rentsch wrote:
> 
> > I develop in an IDLE window.
> > 
> > Module M says 'from service import *'. Next I correct a mistake in
> > function 'service.f'. Now 'service.f' works fine.
> 
> from service import *
> 
> should be considered advanced functionality that is discouraged unless 
> you really know what you are doing, precisely for the problems you are 
> experiencing. You should try to avoid it.
> 
> But putting that aside, if you have done "from service import *" in 
> module m, where are you getting "service.f" from? The only way that is 
> possible is if you ALSO say "import service".
> 
> 
> > I do 'reload (service); reload (M)'.
> > The function 'M.f' still misbehaves.
> > 
> > 'print inspect.getsource (service.f)' and 'print inspect.getsource
> > (M.f)' shows the same corrected code.
> 
> inspect.getsource always looks at the source code on disk, no matter what 
> the byte code in memory actually says.
> 
> > 'print service.f' and 'print M.f' show different ids.
> > 
> > So I do 'del M; reload (M)'. Nothing changes.
> > 
> > I delete M again and run gc.collect () to really clean house. I reload M
> > again and still nothing changes. The id of the reloaded function 'M.f'
> > is still the same as it was before the purge and so M.f still isn't
> > fixed.
> >
> > I know I have more radical options, such as starting a new IDLE window.
> > That would save me time, but I'd like to take the opportunity to
> > understand what is happening. Surely someone out there knows.
> 
> Yes. You have to understand importing. Let's start with the simple:
> 
> import m
> 
> In *very* simplified pseudo-code, this does:
> 
> look for module m in the global cache
> if not there, then:
>     search for m.py
>     compile it to a Module object
>     put the Module object in the cache
> create a new name "m" in the local namespace
> set the name "m" to the Module object in the cache
> 
> Now let's compare it to:
> 
> from m import f
> 
> look for module m in the global cache
> if not there, then:
>     search for m.py
>     compile it to a Module object
>     put the Module object in the cache
> look for object named "f" in the Module object
> create a new name "f" in the local namespace
> set the name "f" to cached object
> 
> The important thing to notice is the the name "f" is a local variable. It 
> doesn't, and can't, remember that it comes from module m. Reloading m 
> can't do anything to f, because the connection is lost.
> 
> Now consider that the object "f" that came from m was itself imported 
> from another module, "service". Reloading service doesn't help, because 
> m.f doesn't know it came from service. Reloading m doesn't help, because 
> all that does is run "from service import f" again, and that just fetches 
> f from the global cache.
> 
> The simplest, easiest way of dealing with this is not to have to deal 
> with it: don't use "from service import f", and ESPECIALLY don't use 
> "from service import *". Always use fully-qualified importing:
> 
> import service
> service.f
> 
> Now "reload(service)" should do what you expect.
> 
> The other way is not to bother with reload. It's not very powerful, only 
> good for the simplest use in the interactive interpreter. Just exit the 
> interpreter and restart it.
> 
> 
> -- 
> Steven

Thank you very much for your excellent explanation!
   I must say that I haven't been using the "from soandso import ..."
formula at all. I thought it might expose names to collision, and why
should I assume the responsibility if I can avoid the problem altogether
using explicit names. If I used the, shall we say, "direct import" this
time it was in an effort to develop a more extensive program. I thought
if a module grows beyond a size that's comfortable to edit, I could just
move select segments to separate files and replace the vacancy with
"from the_respective_segment_module import *", analogous to "#include"
in C.
   The remedy seems to have side-effects that can kill the patient. So
I'll go back to the explicit imports, then. No problem at all. 

Thanking you and the other helpers too

Frederic


-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to