The rules of reference

Gerson Kurz gerson.kurz at t-online.de
Thu Oct 31 13:52:12 EST 2002


Without further ado:

--------- (snip a.py) ----------

num = 42

def print_num():
    global num
    print "a.print_num() called, num is %d" % num

if __name__ == "__main__":
    import b
    print "Step 1: num should be 42"
    print_num()
    num = 60
    print "Step 2: num should be 60"
    print_num()
    print "Step 3: num should *still* be 60, but is probably not:"
    b.do_stuff() 

---------- (snip b.py) ---------

import a

def do_stuff():
    print "b.do_stuff() called"
    a.print_num()

----------------------------------

starting a.py gives the following

Step 1: num should be 42
a.print_num() called, num is 42
Step 2: num should be 60
a.print_num() called, num is 60
Step 3: num should *still* be 60, but is probably not:
b.do_stuff() called
a.print_num() called, num is 42


Frankly, I'm stunned.

This is just a striped down example of something I wanted to do in my
code, and took serious debugging to realize. 

Bug, or Feature, or .... hitherto unrecognized fact about natural
numbers? 

The only thing I can find about it in the FAQ seems section "4.37. How
can I have modules that mutually import each other?", with the
proposed solution "Matthias Urlichs recommends to restructure your
code so that the recursive import is not necessary in the first
place".

ok, so lets restructure that bugger:

------------------ (a2.py) --------------
if __name__ == "__main__":
    import b, c
    print "Step 1: num should be 42"
    c.print_num()
    c.num = 60
    print "Step 2: num should be 60"
    c.print_num()
    print "Step 3: num should *still* be 60, but is probably not:"
    b.do_stuff()
------------------ (b2.py) --------------
import c

def do_stuff():
    print "b.do_stuff() called"
    c.print_num()

print "this is c, don't mess with me."
------------------ (c.py) --------------
num = 42

def print_num():
    global num
    print "c.print_num() called, num is %d" % num

-------------------------------------
This gives me:

this is c, don't mess with me.
Step 1: num should be 42
c.print_num() called, num is 42
Step 2: num should be 60
c.print_num() called, num is 60
Step 2: num should *still* be 60, but is probably not:
b.do_stuff() called
a.print_num() called, num is 42

Way to go, restructured code! 

Oh, and I'm using 

ActivePython 2.2.1 Build 222 (ActiveState Corp.) based on
Python 2.2.1 (#34, Apr 15 2002, 09:51:39) [MSC 32 bit (Intel)] on
win32









More information about the Python-list mailing list