semi-newbie module namespace confusion

P

pnau

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 = 25printing from NSA:
[37, 44]
printing from NSB:
[37, 44]
[37, 44, 'gotcha']
25
666
printing from NSA:
[37, 44, 'gotcha']
abc = 666
 
F

Fredrik Lundh

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>
 
D

David Murmann

Fredrik said:
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.
 
F

Fredrik Lundh

David said:
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>
 
D

David Murmann

Fredrik said:
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...
there's no way to "fix" it without introducing a huge number of inconsistencies.


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.
 
P

pnau

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
 
M

Magnus Lycka

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top