[Tutor] Confusion regarding the 'from' statement

eryksun eryksun at gmail.com
Tue Aug 14 22:00:10 CEST 2012


On Tue, Aug 14, 2012 at 2:24 PM, Mazhar Hussain <yam.matt at gmail.com> wrote:
>
> #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
>
> 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.

mod1 gets a reference to mod2.test, but the mod2 object isn't garbage
collected. A reference exists in sys.modules. After the import, add
the following:

import sys
print sys.modules['mod2']

Also test() can access countChars() and countLines() because it was
defined in the mod2 namespace. In other words, test.__globals__ is
mod2.__globals__. An example:

#mod1.py
import mod2
mod2.test_global()
print mod2.g

#mod2.py
def test_global():
    global g
    g = "I'm in mod2."

#run python mod1.py

Even though test_global is called from mod1, g is created in mod2.

More namespace trivia...
When you run a module as the main script, its name is '__main__' and
other modules can "import __main__". But if you import it by the
filename, you get a new module instance with a separate namespace:

#mod1
if __name__ == '__main__':
    import mod2
    mod2.imp_main() #create g in __main__ and also in mod1
    print g  #__main__
    import mod1  #self import, but mod1 instance, not __main__
    print mod1.g  #mod1

#mod2
def imp_main():
    import __main__
    import mod1
    __main__.g = "__main__"
    mod1.g = "mod1"

#run python mod1.py


More information about the Tutor mailing list