[Tutor] Confusion regarding the 'from' statement

Peter Otten __peter__ at web.de
Tue Aug 14 21:56:34 CEST 2012


Mazhar Hussain wrote:

> Im new to python and theres something thats bothering me for quite a
> time. I read in 'Learning Python' by Mark Lutz that when we use a
> 'from' statement to import a name present in a module, it first
> imports the module then assigns a new name to it(i.e. the name of the
> function,class, etc present in the imported module) and then deletes
> the module object with the del statement. However what happens if I
> try to import a name using 'from' that references a name in the
> imported module that itself is not imported. Consider the following
> example,here there are two modules mod1.py and mod2.py,
> 
> #mod1.py
> from mod2 import test
> test('mod1.py')
> 
> #mod2.py
> def countLines(name):
>     print len(open(name).readlines())
> 
> def countChars(name):
>     print len(open(name).read())
> 
> def test(name):
>     print 'loading...'
>     countLines(name)
>     countChars(name)
>     print '-'*10
> 
> Now see what happens when I run or import mod1
> 
>>>>import mod1
> 
> loading...
> 3
> 44
> ----------
> 
> Here when I imported and ran the 'test' function, it ran successfully
> although I didn't even import countChars or countLines, and the 'from'
> statement had already deleted the mod2 module object.
> 
> SO I basically need to know why does this code work although
> considering the problems I mentioned it shouldn't.

A quick look under the hood:

A module is an object like every other in Python and it will not be deleted 
until all references to it are gone:

>>> class A:
...     def __del__(self): print "I'm gone"
... 
>>> a = b = A()
>>> del a # the object is still referenced by the name 'b'
>>> del b # the point of no return
I'm gone

A reference for every module that was ever imported is kept in a cache 
called sys.modules (a Python dict):

>>> from mod2 import test
>>> import sys
>>> mod2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'mod2' is not defined
>>> "mod2" in sys.modules
True
>>> sys.modules["mod2"].countLines
<function countLines at 0x7f197eeb16e0>
>>> test("mod2.py")
loading...
11
215
----------

Once you delete the module from that cache your little test() function is in 
trouble. While it still keeps a reference to the module's global namespace

>>> del sys.modules["mod2"]
>>> "countLines" in test.__globals__
True

all entries in that namespace were set to None during module cleanup:

>>> test("mod2.py")
loading...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "mod2.py", line 9, in test
    countLines(name)
TypeError: 'NoneType' object is not callable
>>> 




More information about the Tutor mailing list