2

I used to think that once a module was loaded, no re-importing would be done if other files imported that same module, or if it were imported in different ways. For example, I have mdir/__init__.py, which is empty, and mdir/mymod.py, which is:

thenum = None
def setNum(n):
    global thenum
    if thenum is not None:
        raise ValueError("Num already set")
    thenum = n

def getNum():
    if thenum is None:
        raise ValueError("Num hasn't been set")
    return thenum

First few use cases from the same file go according to expectation. This file is ./usage.py, the same folder mdir is in:

import mdir.mymod

mdir.mymod.setNum(4)
print mdir.mymod.getNum()

from mdir import mymod
print mymod.getNum()

from mdir.mymod import *
print getNum()
try:
    setNum(10)
except ValueError:
    print "YHep, exception"

The output is as expected:

4
4
4
YHep, exception

However, if I muck with the system path, then it looks like the module is imported anew:

#BEHOLD
import sys
sys.path.append("mdir")
import mymod
try:
    mymod.getNum()
except ValueError:
    print "Should not have gotten exception"

mymod.setNum(10)
print mymod.getNum()
print mdir.mymod.getNum()

That code, running after the previous code, yields:

Should not have gotten exception
10
4

What gives?

1 Answer 1

4

mymod and mdir.mymod are considered different modules - here's somewhat related discussion: http://code.djangoproject.com/ticket/3951

Explanation:

It's best to play with python interactive interpreter and see for yourself. I created directory (package) mydir under some directory and inside it two files (modules) - __init__.py and mymod.py, both empty. I started python inside of directory containing mydir. Now see what happens:

>>> import mydir.mymod
>>> from mydir import mymod
>>> mymod == mydir.mymod
True

Why are mymod and mydir.mymod considered the same thing? Well, both names refer to the same module object - modules equality is determined by their paths comparison:

>>> mymod
<module 'mydir.mymod' from 'mydir\mymod.py'>
>>> mydir.mymod
<module 'mydir.mymod' from 'mydir\mymod.py'>

Now, if I alter sys.path to contain mydir and import mymod in such a way that path of imported module will seem to be different:

>>> import sys
>>> sys.path.append( "d:/zrodla/stack/mydir" )
# note that importing mymod (and not mydir.mymod) prior to appending mydir to 
# path would cause an error
>>> mymod2
<module 'mymod' from 'd:/zrodla/stack/mydir\mymod.pyc'>
>>> mymod2 == mydir.mymod
False

then resulting module objects will not compare equal. This way one module will be imported twice - it's normal and that's the way python works. Just remember that imported modules are identified by their paths - more specifically by 'dotted paths' I think - look at sys.modules keys:

>>> [x for x in sys.modules.keys() if "my" in x]
['mydir', 'mymod', 'mydir.mymod']

I hope it's clear now.

Sign up to request clarification or add additional context in comments.

2 Comments

but before the latest set of imports, mdir.mymod seemed to be the same module.
@Claudiu sorry for the wait, I added an explanation, hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.