What is Best Way to Handle Files in Python

38204
11
06-13-2017 11:36 AM
PatrickMcKinney1
Occasional Contributor III

I often write the results of geoprocessing scripts to a text file.  After doing some research, I learned I'm not using best practices for closing the file.  I'm not opening the file using the with keyword, so the file may not close if there is an error.  If there is an error, I need to be able to write the error message to the text file.  It looks like I could use the finally keyword or with keyword to ensure the file closes.    

Which of these options is better? And if I've made any errors in how I think I could improve my implementation, please let me know. Thanks!  

Method #1

try:
   # log file to write to
   logFile = r'path\tofile\fileName.txt'

   # open file in write mode
   report = open(logFile, 'w')

   # geoprocessing stuff

   # write to report
   report.write('some message')

except Exception as e:
   # get line number and error message
   report.write('an error message')

finally:
   report.close()‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

   

Method #2

try:
   # log file to write to
   logFile = r'path\tofile\fileName.txt'
   
   # open file in write mode
   with open(logFile, 'w') as f:
      # geoprocessing stuff
   
      # write to report
      f.write('some message')

except Exception as e:
   # get line number and error message
   with open(logFile, 'a') as f:
      f.write('an error message')
11 Replies
PatrickMcKinney1
Occasional Contributor III

I had to look up OP to confirm you were referring to me.  My scripts bail if there is an error.  My scripts are doing things like rebuilding address locators, rebuilding tiles for cached services, running replication, etc.  I basically want to know if the task ran successful or not.  If it failed, that is okay, I just want to know why it failed.

0 Kudos
ClintonDow1
Occasional Contributor II

It seems like there are several possible error states you want to handle here:

  • LogFile does not exist when trying to write to it 
  • Error thrown in 'Geoprocessing Stuff' section

For the first point, the mode argument in open() can include a '+' character which will cause the file to be created if it doesn't exist. If the directory itself doesn't exist then you'll see a FileNotFoundException. This can be handled as such:

try:
  f = open(log_file, 'a+')   # use 'a+' to append, 'w+' to truncate
except FileNotFoundException:
  # handle the file system issues
‍‍‍‍‍‍‍‍‍

Then for the second point, you'd want to handle the Geoprocessing Errors inside the with block as such:

with f:
  log_msg = ""
  try:
    # Geoprocessing Stuff
    log_msg += do_gp_stuff_step1()
    log_msg += do_gp_stuff_step2()
    log_msg += 'Success!'
  except Exception as e:  # Be more specific based on your code
    log_msg += e
  finally:
    # Clean up Geoprocessing stuff 
    f.write(log_msg)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Obviously you'd want to make things more readable with string formatting, or can build log_msg in other ways, but this is the basic pattern that I would recommend.