By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,814 Members | 1,111 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,814 IT Pros & Developers. It's quick & easy.

Weird import behavior

P: n/a
Hi,

I have been using Python for a while but today I came across a really
strange behavior:

While poking around in Queue.py due to problems with importing this
module from a thread I got an error that a module that I imported on
top of the file could not be accessed. I reduced the problem to this
small script:

import string
import os

class T:
def __init__(self):
try:
print 'xxx nothing to do'
except ImportError:
print 'got an import error'
import os as string

print 'xxxx string module', string

t=T()
The import clause in the except statement (although never executed)
removes the reference to the string module imported at the beginning of
the script. Any idea why this is the case?

Thanks,
Tommy

Oct 25 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Tommytrojan wrote:
import string
import os

class T:
def __init__(self):
try:
print 'xxx nothing to do'
except ImportError:
print 'got an import error'
import os as string

print 'xxxx string module', string

t=T()
The import clause in the except statement (although never executed)
removes the reference to the string module imported at the beginning of
the script. Any idea why this is the case?


Quoting the error message would have made the answer instantly clear to
everyone, including probably yourself:

UnboundLocalError: local variable 'string' referenced before assignment

Assigning to the variable 'string' anywhere in the function makes it a
local variable throughout the function. Use 'global string' if you want the
import to affect the global variable.
Oct 25 '05 #2

P: n/a
Duncan,

thanks for your quick reply. I guess I should have included the output.
I thought I was clear in the error description.
The problem is that I never assign to 'string'. I only reference it (as
the error message correctly states). If you comment out the import
statement in the except clause the program runs fine. Now notice that
the exception hander never gets executed! Any explanation?

Oct 25 '05 #3

P: n/a
Tommytrojan wrote:
Duncan,

thanks for your quick reply. I guess I should have included the output.
I thought I was clear in the error description.
The problem is that I never assign to 'string'. I only reference it (as
the error message correctly states). If you comment out the import
statement in the except clause the program runs fine. Now notice that
the exception hander never gets executed! Any explanation?

You have an assignment to 'string' in the function (import, class and def
statements are all equivalent to assignment statements so far as scoping
is concerned). It doesn't matter whether or not the assignment gets
executed: the compiler flags the variable as a local variable.

See the Python FAQ, 1.2.2:

1.2.2 What are the rules for local and global variables in Python?

In Python, variables that are only referenced inside a function are
implicitly global. If a variable is assigned a new value anywhere within
the function's body, it's assumed to be a local. If a variable is ever
assigned a new value inside the function, the variable is implicitly local,
and you need to explicitly declare it as 'global'.
Oct 25 '05 #4

P: n/a
"Tommytrojan" wrote:
thanks for your quick reply. I guess I should have included the output.
I thought I was clear in the error description.
The problem is that I never assign to 'string'. I only reference it (as
the error message correctly states). If you comment out the import
statement in the except clause the program runs fine. Now notice that
the exception hander never gets executed! Any explanation?


the language reference has the full story:

http://docs.python.org/ref/naming.html

"If a name is bound in a block, it is a local variable of that
block." /.../

"The following constructs bind names: formal parameters
to functions, import statements, class and function definitions
(these bind the class or function name in the defining block),
and targets that are identifiers if occurring in an assignment,
for loop header, or in the second position of an except
clause header. The import statement of the form "from ...
import *" binds all names defined in the imported module,
except those beginning with an underscore. /.../

A target occurring in a del statement is also considered bound
for this purpose (though the actual semantics are to unbind
the name). /.../

If a name binding operation occurs anywhere within a code block,
all uses of the name within the block are treated as references to
the current block."

</F>

Oct 26 '05 #5

P: n/a
Thanks for the clarification. I never ran into this before although I
have been working with Python for over 8 years. Good to learn something
new.

Cheers,
Thomas

Oct 26 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.