try...except...finally problem in Python 2.5

R

redawgts

I keep getting this error "local variable 'f' referenced before
assignment" in the finally block when I run the following code.

try:
f = file(self.filename, 'rb')
f.seek(DATA_OFFSET)
self.__data = f.read(DATA_SIZE)
self.isDataLoaded = True
except:
self.isDataLoaded = False
finally:
f.close()

Can someone tell me what's wrong with the code? Am I doing something
wrong? I'm somewhat new to python but this makes sense to me.
 
A

Andrew Koenig

I keep getting this error "local variable 'f' referenced before
assignment" in the finally block when I run the following code.

try:
f = file(self.filename, 'rb')
f.seek(DATA_OFFSET)
self.__data = f.read(DATA_SIZE)
self.isDataLoaded = True
except:
self.isDataLoaded = False
finally:
f.close()

Can someone tell me what's wrong with the code? Am I doing something
wrong? I'm somewhat new to python but this makes sense to me.

If the call to file raises an exception, then variable f won't have been
created.

Here's a simple example:

def f():
throw 42
try:
x = f()
except:
print x

Try it and see what happens. While you're at it, you might try to figure
out what you would like it to print.
 
R

Robert Kern

redawgts said:
I keep getting this error "local variable 'f' referenced before
assignment" in the finally block when I run the following code.

try:
f = file(self.filename, 'rb')
f.seek(DATA_OFFSET)
self.__data = f.read(DATA_SIZE)
self.isDataLoaded = True
except:
self.isDataLoaded = False
finally:
f.close()

Can someone tell me what's wrong with the code? Am I doing something
wrong? I'm somewhat new to python but this makes sense to me.

Move the "f = file(self.filename, 'rb')" above the try:. If opening the file
happens to throw an exception, then the assignment will never happen and there
will be no 'f' to close.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
L

Larry Bates

redawgts said:
I keep getting this error "local variable 'f' referenced before
assignment" in the finally block when I run the following code.

try:
f = file(self.filename, 'rb')
f.seek(DATA_OFFSET)
self.__data = f.read(DATA_SIZE)
self.isDataLoaded = True
except:
self.isDataLoaded = False
finally:
f.close()

Can someone tell me what's wrong with the code? Am I doing something
wrong? I'm somewhat new to python but this makes sense to me.
finally: block is executed even if there is an exception in which case f
hasn't been defined. What you want is:

try:
f = file(self.filename, 'rb')
f.seek(DATA_OFFSET)
self.__data = f.read(DATA_SIZE)
self.isDataLoaded = True

except:
isDataLoaded=False

else:
f.close()

-Larry
 
P

Paul Rubin

redawgts said:
try:
f = file(self.filename, 'rb') ...
Can someone tell me what's wrong with the code?

Various people have explained the error: if the file open attempt
fails, f is never assigned. Doing it the right way (i.e. handling the
potential exceptions separately) with try/except statements is messy,
so it's worth mentioning that 2.5 adds the new "with" statement to
clean this up. I'm not using 2.5 myself yet so maybe someone will
have to correct me, but I think you'd write:

from __future__ import with_statement

self.isDataLoaded = False
with open(self.filename, 'rb') as f:
f.seek(DATA_OFFSET)
self.__data = f.read(DATA_SIZE)
self.isDataLoaded = True

and that should handle everything, closing the file automatically.
 
S

Steven D'Aprano

Various people have explained the error: if the file open attempt
fails, f is never assigned. Doing it the right way (i.e. handling the
potential exceptions separately) with try/except statements is messy,
so it's worth mentioning that 2.5 adds the new "with" statement to
clean this up. I'm not using 2.5 myself yet so maybe someone will
have to correct me, but I think you'd write:

from __future__ import with_statement

self.isDataLoaded = False
with open(self.filename, 'rb') as f:
f.seek(DATA_OFFSET)
self.__data = f.read(DATA_SIZE)
self.isDataLoaded = True

and that should handle everything, closing the file automatically.


I don't have Python 2.5 here to experiment, but how is that different from
this?


self.isDataLoaded = False
try:
f = open(self.filename, 'rb')
f.seek(DATA_OFFSET)
self.__data = f.read(DATA_SIZE)
self.isDataLoaded = True
except:
pass
else:
pass

(apart from being four lines shorter)
 
P

Paul Rubin

Steven D'Aprano said:
self.isDataLoaded = False
try:
f = open(self.filename, 'rb')
f.seek(DATA_OFFSET)
self.__data = f.read(DATA_SIZE)
self.isDataLoaded = True
except:
pass
else:
pass

(apart from being four lines shorter)

Your version never closes the file.
 
S

Steven D'Aprano

Your version never closes the file.


Yes it does. Eventually f goes out of scope and is closed automatically.

I don't see where the "with" version closes the file either. How does it
know that I want to call the f's close() method, rather than, say,
f.exit() or f.do_something_else()?
 
S

Steven D'Aprano

Replying to my own question...

I don't see where the "with" version closes the file either. How does it
know that I want to call the f's close() method, rather than, say,
f.exit() or f.do_something_else()?

Ah, I *think* I see... file objects in Python 2.5 are objects that know
how to work with the "with" statement; that is they obey the "context
management" protocol and have __enter__ and __exit__ methods that do the
right thing to make everything work correctly.

http://docs.python.org/whatsnew/pep-343.html

Have I got it right?
 
P

Paul Rubin

Steven D'Aprano said:
Yes it does. Eventually f goes out of scope and is closed automatically.

Oh right, however you can't really predict when the closure occurs,
unless you're relying on current CPython artifacts.

Re your other post: yes, PEP 363 explains how the "with" statement
calls the __exit__ method.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top