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