11

What is the best way in python to handle reading a file that may potentially not exist?

Currently I have the following:

    try:
        with open(filename, "r") as f:
            return f.read()
    except IOError:
        return False

Is this the best way to do it or is this wrong on any level at all?

I guess my biggest concerns are:

  1. Catching the exception only to return false
  2. Maybe i am missing a 'Python' way of silently missing the error for a missing file
martineau
  • 119,623
  • 25
  • 170
  • 301
Marty Wallace
  • 34,046
  • 53
  • 137
  • 200
  • that's pretty good. The only problem that I can think of is that there could be an existing file that you can't open (e.g. permissions are set wrong). This will return `False` for that case, but you haven't defined what you want to happen there ... – mgilson May 25 '13 at 17:27
  • I do think that is the best way. See [this response to similar question][1] [1]: http://stackoverflow.com/a/85237/17001 – kelsmj May 25 '13 at 17:28

3 Answers3

12

A try / except is indeed the best way.

jamylak
  • 128,818
  • 30
  • 231
  • 230
Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251
  • 1
    Is returning false from the caught exception ok? – Marty Wallace May 25 '13 at 17:28
  • 1
    @MartyWallace, depends on how you planning on using the function. I'm leaning toward a no, though. Personally, I just let errors bubble up until it reaches a point at which I know what to do with the error. – Tyler Crompton May 25 '13 at 17:29
  • Well this is a function that reads a file based on a key (a cached file) so it is perfectly plausible that the file wont exist yet. In that sense it isnt really an exception as such - simply that python is forcing me to treat it as an exception – Marty Wallace May 25 '13 at 17:32
  • 1
    @MartyWallace, well we don't know what the rest of your code looks like or exactly what you're doing. If you really must have the question answered, I'd encourage you to visit codereview.stackexchange.com. – Tyler Crompton May 25 '13 at 17:45
  • @MartyWallace: You don't return False from an exception, you return False from a function. You should only return False because of an error if it makes sens for the rest of the function. Would the function otherwise return True/False? Then it makes sense. If you are returning False to signal an error, it's better to not catch the exception. – Lennart Regebro May 26 '13 at 03:24
  • @MartyWallace: "In that sense it isnt really an exception as such" - an exception doesn't have to be some dramatic and rare failure, I find the best way to think of them is just that an operation could not be completed as requested. Much of the time a function cannot determine what the appropriate response to such a failure is, so the raising of an exception transfers control back to the caller and says "I don't know how to deal with this, so you take care of it". – Crowman Sep 14 '13 at 17:10
2

A try except block will catch the error, but you might not want to suppress the error.

If you're writing a function that returns the content read from the file, then it would be wiser to return '' instead of False. It's generally a good idea for a function to only return one type. Something like:

try:
    with open(filename) as f:
        return f.read()
except IOError:
    return ''

Really it seems like you're signalling an error condition with a return. If so, you're usually better off just letting the exception propagate out of the function. It's not pythonic to use a returned value to signal an exceptional condition.

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
  • how would you handle my situation, where i am opening a file that might not be present yet. The presence of the file is no indication of an error, simply means that the file cant be read from and no indication that something is wrong in the system – Marty Wallace May 25 '13 at 17:46
  • @MartyWallace It depends on what you're doing with the file content. I would think an empty string is safe enough for the general case. Alternatively, use a try/except/else, where the else handles the case that the file is open and has been read. – Ryan Haining May 25 '13 at 17:49
2
import os

if os.path.isfile('./file.txt'):
  # do something with the file
imaginabit
  • 409
  • 4
  • 9