Reload() Confusion

Mel Wilson mwilson at the-wire.com
Sat Mar 20 17:55:17 EST 2004


In article <u4l450hv7isekpk09upvhcpi3b18m3p8a7 at 4ax.com>,
David MacQuigg <dmq at gain.com> wrote:
>I'm going to be teaching EEs some basic Python using the first few
>chapters of Learning Python, 2nd ed. by Mark Lutz.  The discussion on
>Reloading Modules starting on page 266 is confusing and I believe
>incorrect.  On page 266 it says that a reload "changes the existing
>module object in place."  That's a little vague, but on page 267 it
>says "every reference to a module object anywhere in your program is
>automatically affected by a reload."
>
>It is my understanding that the reloaded objects become *new* objects
>in memory, available only via a fully-qualified reference to the new
>module.  The old objects remain in memory until the last reference to
>them is gone.

   It seems to me that the module keeps its identity over
the reload:

Python 2.3 (#46, Jul 29 2003, 18:54:32) [MSC v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> id(re)
9940176
>>> reload(re)
<module 're' from 'E:\bin\Python23\lib\re.py'>
>>> id(re)
9940176
>>>

>
>I've re-written the section on Reload Basics, and I would like to get
>some comments, both on correctness and clarity.
>
>http://ece.arizona.edu/~edatools/Python/Reload.htm
>
>Your help will be appreciated, both by me and by the students
>struggling through this the first time.
>
   I agree with you.  It seems that the module code is
re-executed in the previously-existing modules namespace.
Wherever that code created new objects the first time, it
will create brand-new objects the second time.  Small
integers and interned strings will keep their identities (of
course), as will objects referenced through other modules.
Nothing is explicitely deleted, so bindings can be left over
from the modules prior incarnation.
No other namespaces will be affected except when code in the
module explicitely calls for it.

For what it's worth, the following code:

#=======================
"""M1 version 1"""
a=1
b=2
c=[1]
d=[2]

#=======================
"""M1 version 2"""
a=1
b=4
c=[3]
e=[4]

#=======================
"""test_reload.py"""
import os, shutil
def module_contents (M):
    print "Doc: ", M.__doc__
    for k, v in M.__dict__.items():
        if not k.startswith ("__"):
            print "%s:\t%d\t%s" % (k, id(v), v)

def grab_contents (M):
    d = {}
    for k, v in M.__dict__.items():
        if not k.startswith ("__"):
            d[k] = v
    return d

#os.remove ("M1.pyc")
shutil.copyfile ("M1_1.py", "M1.py")
import M1
module_contents (M1)
mc = grab_contents (M1)

print
os.remove ("M1.pyc")
shutil.copyfile ("M1_2.py", "M1.py")
reload (M1)
module_contents (M1)

print '\nMC:'
for k, v in mc.items():
    print "%s:\t%d\t%s" % (k, id(v), v)




Which gives

F:\home\mwilson\Projects\python\testscript>python test_reload.py
Doc:  M1 version 1
a:      8463376 1
c:      9940432 [1]
b:      8470496 2
d:      9940368 [2]

Doc:  M1 version 2
a:      8463376 1
c:      9940272 [3]
b:      8468480 4
e:      9937584 [4]
d:      9940368 [2]

MC:
a:      8463376 1
c:      9940432 [1]
b:      8470496 2
d:      9940368 [2]


The second os.remove seems to be required in case the reloaded
version of M1.py is older than the imported one.

        Regards.        Mel.



More information about the Python-list mailing list