semi-newbie module namespace confusion

Discussion in 'Python' started by pnau@sjm.com, Oct 4, 2005.

  1. Guest

    I've stuck my neck out and am in the integration stage of a rather
    important project at my company, which wears dot net blinders. The
    program is not too big: I've cranked out 3K lines of code, quite a bit
    of which is unit tested, but my eyes are starting to glaze, and now I'm
    stuck (and not just my neck :). If I can get the show back on the
    road and bring it to a conclusion, I'll be able to persuade a lot of
    people to look closely at Python (not to mention the job retention
    aspect :).

    The main jist of the problem is that I'm trying add data from one
    module to a list and a dictionary in another module, and it doesn't
    seem to stick over there.

    The programs below seem to illustrate the issue. (The results follow
    the programs).
    Why are the results different from runs of the two programs? The
    output of nameSpaceTestB.py makes sense to me, but I just don't get why
    nameSpaceTestA.py does what it does.

    I'm sure the reason is very simple, but I just don't see it. Please,
    can someone shed some light on the issue for me?

    Thanks!

    ~Peter

    ---------------------------------
    nameSpaceTestA.py:
    import nameSpaceTestB as NSB

    normalQ = [ 37]
    abc = 25

    def indirect( ) :
    normalQ.append( 44)

    print "printing from NSA:"
    print normalQ

    NSB.updateNSA( )

    print "printing from NSA:"
    print normalQ
    print "abc = %d" % abc

    if __name__ == '__main__' :

    indirect()

    ---------------------------------
    nameSpaceTestB.py:
    import nameSpaceTestA as NSA

    def updateNSA( ) :
    print "printing from NSB:"
    print NSA.normalQ
    NSA.normalQ.append( "gotcha")
    print NSA.normalQ
    print NSA.abc
    NSA.abc = 666
    print NSA.abc


    if __name__ == '__main__' :
    NSA.indirect()
    ---------------------------------
    > py24 nameSpaceTestA.py

    printing from NSA:
    [37, 44]
    printing from NSB:
    [37]
    [37, 'gotcha']
    25
    666
    printing from NSA:
    [37, 44]
    abc = 25
    >

    ---------------------------------
    > py24 nameSpaceTestB.py

    printing from NSA:
    [37, 44]
    printing from NSB:
    [37, 44]
    [37, 44, 'gotcha']
    25
    666
    printing from NSA:
    [37, 44, 'gotcha']
    abc = 666
    , Oct 4, 2005
    #1
    1. Advertising

  2. wrote:

    > The main jist of the problem is that I'm trying add data from one
    > module to a list and a dictionary in another module, and it doesn't
    > seem to stick over there.
    >
    > The programs below seem to illustrate the issue. (The results follow
    > the programs).
    > Why are the results different from runs of the two programs? The
    > output of nameSpaceTestB.py makes sense to me, but I just don't get why
    > nameSpaceTestA.py does what it does.
    >
    > I'm sure the reason is very simple, but I just don't see it. Please,
    > can someone shed some light on the issue for me?


    running a piece of python code as a script isn't the same thing as
    importing it as a module:

    "If you run a module as a script (i.e. give its name to the inter-
    preter, rather than importing it), it's loaded under the module
    name __main__.

    If you then import the same module from your program, it's re-
    loaded and reexecuted under its real name. If you're not careful,
    you may end up doing things twice."

    http://effbot.org/zone/import-confusion.htm

    try changing your "printing from"-statements to

    print "printing from", __name__

    to see what you're really doing.

    </F>
    Fredrik Lundh, Oct 4, 2005
    #2
    1. Advertising

  3. Fredrik Lundh wrote:
    > running a piece of python code as a script isn't the same thing as
    > importing it as a module:


    I ran into the same problem some time ago and even wanted to post here
    about it, but found out that it had been reported as a bug three times
    at sourceforge (if i remember correctly). The comments there explained
    it of course, but I still think that this behavior is somehow "wrong".
    I like to think of the import statement as a way to provide the names
    defined in a module to the current namespace, so there is no "this gets
    evaluated twice".
    Now i wonder how difficult it would be to "correct" the behavior? And
    would such a change break any code?

    David.
    David Murmann, Oct 4, 2005
    #3
  4. David Murmann wrote:

    > I ran into the same problem some time ago and even wanted to post here
    > about it, but found out that it had been reported as a bug three times
    > at sourceforge (if i remember correctly). The comments there explained
    > it of course, but I still think that this behavior is somehow "wrong".
    >
    > I like to think of the import statement as a way to provide the names
    > defined in a module to the current namespace, so there is no "this gets
    > evaluated twice".


    are you sure you understand the problem? import does exactly what you
    say; it creates a module object and populates it by running the code in the
    module.

    the problem is that when you hand Python a chunk of code (a script), it
    doesn't necessarily know where it came from. and even if you know the
    filename it came from, there's no way to know if that chunk actually corre-
    sponds to a module somewhere out there (the import system can map a
    module name to a file, but it cannot map a file to a module name).

    > Now i wonder how difficult it would be to "correct" the behavior?


    there's no way to "fix" it without introducing a huge number of inconsistencies.

    > And would such a change break any code?


    any code that uses the "if __name__ == "__main__" pydiom, for a start.

    </F>
    Fredrik Lundh, Oct 4, 2005
    #4
  5. Fredrik Lundh wrote:
    > David Murmann wrote:
    >
    >> I ran into the same problem some time ago and even wanted to post here
    >> about it, but found out that it had been reported as a bug three times
    >> at sourceforge (if i remember correctly). The comments there explained
    >> it of course, but I still think that this behavior is somehow "wrong".
    >>
    >> I like to think of the import statement as a way to provide the names
    >> defined in a module to the current namespace, so there is no "this gets
    >> evaluated twice".

    >
    > are you sure you understand the problem? import does exactly what you
    > say; it creates a module object and populates it by running the code in the
    > module.

    maybe i don't... but i'm not convinced yet, see below.

    > the problem is that when you hand Python a chunk of code (a script), it
    > doesn't necessarily know where it came from. and even if you know the
    > filename it came from, there's no way to know if that chunk actually corre-
    > sponds to a module somewhere out there (the import system can map a
    > module name to a file, but it cannot map a file to a module name).

    well, in my opinion python is not trying hard enough. to me it is
    immediately obvious that the main module gets evaluated twice and
    i am rather sure that one could introduce some magic of the kind
    "oh, i reevaluate the main script here, the module does not get filled
    the usual way but uses the existing objects instead". this would have
    to happen on a very low level (when the file i just read from is known)
    but i think it would be possible. whether the effort to do so is worth
    it, is a different question...

    >> Now i wonder how difficult it would be to "correct" the behavior?

    >
    > there's no way to "fix" it without introducing a huge number of inconsistencies.
    >
    >> And would such a change break any code?

    >
    > any code that uses the "if __name__ == "__main__" pydiom, for a start.

    i wouldn't lose that, the main module should still be named "__main__",
    it should just get more names (somehow) :)
    i see, it's difficult at the moment

    hoping i'm not completely wrong here, David.
    David Murmann, Oct 4, 2005
    #5
  6. Guest

    I'm not going to quote anything (except a URI), but thanks very much
    for your help, especially http://effbot.org/zone/import-confusion.htm.


    Almost certainly the source (and solution) to my problem lies in what
    you guys have brought out. I'm no longer stuck (at least I hope not),
    and I have knowledge to use in working out the solution.

    Kind Regards,

    ~Peter
    , Oct 4, 2005
    #6
  7. Magnus Lycka Guest

    wrote:
    > The main jist of the problem is that I'm trying add data from one
    > module to a list and a dictionary in another module, and it doesn't
    > seem to stick over there.


    It's probably best to avoid any circular depentencies, but as
    long as you make sure you really use your modules as modules,
    and not one of them aas a main prorgam, I think it should work.

    $ cat > a.py
    import b
    def set_b(n):
    b.b=n
    $ cat > b.py
    import a
    def set_a(n):
    a.a=n
    $ python
    Python 2.2.3 (#1, Feb 2 2005, 12:20:51)
    [GCC 3.2.3 20030502 (Red Hat Linux 3.2.3-49)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import a,b
    >>> a.set_b('B')
    >>> b.set_a('A')
    >>> a.a

    'A'
    >>> b.b

    'B'
    >>>
    Magnus Lycka, Oct 7, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?RFQ=?=
    Replies:
    1
    Views:
    1,735
    Brock Allen
    Apr 4, 2005
  2. Alf P. Steinbach
    Replies:
    3
    Views:
    694
    Peter Forthmann
    Jan 30, 2004
  3. mike kreiner
    Replies:
    11
    Views:
    549
    Bengt Richter
    Dec 30, 2004
  4. James Stroud

    py2app semi-standalone semi-works

    James Stroud, Oct 4, 2006, in forum: Python
    Replies:
    2
    Views:
    679
    James Stroud
    Oct 4, 2006
  5. Ulrich Dorda
    Replies:
    4
    Views:
    424
Loading...

Share This Page