why is this namespace weirdness happening?

chris_barker at my-deja.com chris_barker at my-deja.com
Wed Jan 10 12:50:13 EST 2001


In article <93i3f7$122$1 at nnrp1.deja.com>,
  Preston Landers <prestonlanders at my-deja.com> wrote:

> It seems that on the file1 "bar" line, if the 'import file2' above it
is
> commented out, the file2.bar reference will fail (file2 being the
> unrecognized item.)  Despite the 'import file2' at the top of the
file.
> It seems to be due to the 'import file2' following the statement.
> Python seems to be scanning ahead for imports...?

Actually, this is quite consistant wioth Python's way of dealing with
namespaces in functions. see this example:

a = 5
def spam():
	print "a :", a
	a = 6
	print "a :", a

The first reference to "a" will fail, but if you comment out the "a = 6"
line, it will access the a already defined. What has happened is that
when Python byte-compiled the function, it noticed that an "a" has been
defined in the function, so it won't use the global "a". NOte that
defining "a" in the function does NOT change the value of the global
"a".

Importing is the same. when you import a module in a function, you are
assiging the name, "file2" to the contents of the module in "file2.py"
IN THAT FUNCTION. Python knows you are doing this, so it won't let you
use the global version of that name.

> I know that doing an import inside a function is not neccesary if you
> have imported the module at the top of the file.  However, it seems
> strange that it only fails if there is an odd number of import
> statements for that module.

It's not a matter of odd number, it's a matter of at least one, and if
you do import it, you have to do so before using it. If you leave only
the first import in place, it will work fine. Any additional imports in
the function will do nothing.

The reason you might want to import the module in your function is that
you may not know know what was done to it outside the function. For
example:

import file2

new_name = file2
del file2

def foo():
	import file2
	# the line below fails if the line above is cmted out
	# but works fine if present
	print "file2 bar: ", file2.bar
	#import file2
	print "file2 baz: ", file2.baz


foo()

without the import line in foo(), it will fail. Note that you are still
working with the saem module, even if it has been renamed, as is in this
example:

import file2

new_name = file2
del file2

def foo():
	import file2
	# the line below fails if the line above is cmted out
	# but works fine if present
	print "file2 bar: ", file2.bar
	#import file2
	print "file2 baz: ", file2.baz
	file2.baz = 10

print "new_name.baz:",new_name.baz

foo()

print "new_name.baz:",new_name.baz

And yes, this does take some getting used to, but it does follow some
pretty simple logic, once you get python's "everything is a reference"
and "mutable types" concepts.

-Chris




Sent via Deja.com
http://www.deja.com/



More information about the Python-list mailing list