[Tutor] try and file existence

Cameron Simpson cs at zip.com.au
Sat Aug 15 04:00:10 CEST 2015


On 14Aug2015 18:28, Clayton Kirkwood <crk at godblessthe.us> wrote:
>try:
>    fp = open( user_preferences )
>except( PermissionError ):
>else:
>    with open(user_preferences ) as f:
>
>I originally only had the bottom open statement. Ran but file didn't exist,
>and my run failed with file doesn't exist. I figured I'd check to see if the
>file existed. This is one of those situations where a search of
>documentation for fd_exist (which I thought I'd seen once), or exist turns
>up either nothing or nothing relevant. I finally found that the try: clause
>with the open statement might help and I copied the snippet to my code. I am
>getting an indentation error: expected an indent block. What is wrong, and
>what is the best way to find out if a file exists?

In purely syntactic terms you need some code in the suite under the "except" 
clause, and you don't want the brackets:

    try:
        fp = open( user_preferences )
    except PermissionError as e:
        print("open(%r) fails: %s" % (user_preferences, e))
    else:
        with open(user_preferences ) as f:

In logical terms, the "with" is not wanted - you're opening the file again.  
Leaving aside the logical issue there, this structure (test then operate) is 
also racy: suppose the file has its attributes changed or is removed between 
the first open and the second.

Next: you're catching PermissionError. That normally means that you have not 
got rights for opening the file; you will get a different exception if the file 
does not exist. You're being too precise if you want both.

But maybe you don't. You need to decide 

Finally, the usual Python pattern is not to catch exceptions _at all_ unless 
you have a deliberate polciy plan for what to do. Normally you would have some 
function looking like this:

  def read_prefs(filename):
    prefs = {}
    with open(filename) as fp:
      ... read preferences, save in prefs dict for example ...
    return prefs

If the file is missing or you have no permissions, that will raise an 
exception. Let it!

Then in an outer layer of your program you might catch the exception, where you 
can make a policy decision because you have a wider view of what is going on:

  try:
    prefs = read_prefs(prefs_filename)
  except FileNotFoundError as e:
    print("warning: file not found: %r: %s" % (prefs_filename, e))
    # proceed with empty preferences, not an error
    prefs = {}

This bit of code catches _only_ FileNotFoundError on the (presumed) policy that 
a missing preferences file is ok - your program will proceed with default 
behaviours - but any _other_ kind of exception is not expected - let your 
program abort! Do not proceed!

Cheers,
Cameron Simpson <cs at zip.com.au>

Capitalism is the extraordinary belief that the nastiest of men, for the
nastiest of reasons, will somehow work for the benefit of us all.
- John Maynard Keynes


More information about the Tutor mailing list