0

Friends,

I was trying to open a file with try/except block.

try:
    with open(finput[1], "r") as f:
        for line in f:
            if "NQ" in line[:2]:
                nq = int(line[-3:].strip())

except EnvironmentError:
    print(("Oops! File \"{:s}\" does not exist!").format(f))
#    print(("Oops! File \"{:s}\" does not exist!").format(finput[1]))
    sys.exit(0)

when I use finput[1] in except (i.e. that is commented now), it workes fine and gives the file name as intended. But if I use f (as I have tried to open the file finput[1] as f), it gives me error: Traceback (most recent call last): File "readspr.py", line 30, in print(("Oops! File \"{:s}\" does not exist!").format(f)) NameError: name 'f' is not defined

I am not much experienced in python (just know coding, but not how it works.). So, my explanation to this is: since, opening of the file as f failed, nothing is stored in f; and hence it is undefined.

But, on the other hand, it seems, python will try to open the file as f and hence, whatever is there in finput[1] is assigned to f as variable string and python has failed to open the file f.

I am not sure what is the case here. I tried to understand it from many piece in internet (i.e. 7.2.1 of this, the accepted answer here among others) but just found what I use it for: simplifying exception handling.

It will be of help to me if you kindly explain why it does not take f as exception.

Community
  • 1
  • 1
BaRud
  • 3,055
  • 7
  • 41
  • 89

1 Answers1

2

The problem isn't actually one of scope (see Variable defined with with-statement available outside of with-block?). The problem is that if an exception happens inside open, the as f statement is never executed, and thus f is not yet defined. If the failure happened inside the with block, then f would still be a valid reference.

In other words, there's nothing special about the with statement here. Your particular case is semantically equivalent to trying to do the following:

try:
    f = open(filename)
except EnvironmentError:
    # Trying to use f here is invalid, since it was never defined if open failed
Community
  • 1
  • 1
aruisdante
  • 8,875
  • 2
  • 30
  • 37
  • Thanks for your reply. But, i have one problem in getting this completely. Is there any way that `with` block fails when the `open` block is ok? – BaRud Feb 15 '15 at 01:08
  • The `with EXP as VAR:` syntax is part of the [language specification](https://www.python.org/dev/peps/pep-0343/), so if that failed it would be a pretty serious bug in a Python implementation. Not really sure if that's exactly what you're asking though. If you mean 'can code that happens inside the indented scope of the `with` statement `raise`', then of course, just like it can anywhere else inside a python program. `f` would still be defined in that case though. – aruisdante Feb 15 '15 at 02:26
  • To be more clear, the reason you wrap `open` in a `with` is so that `File.close()` is called automatically on exit from the `with` statement's scope, whether that point is reached because the code block completed successfully or because it threw an exception. [Context managers](https://docs.python.org/2/library/contextlib.html) are used to ensure that resources aren't leaked/are always cleaned up even in the event of exceptions being thrown, that's their primary purpose. – aruisdante Feb 15 '15 at 02:30