[Tutor] What's the best way to ask forgiveness here?

Steven D'Aprano steve at pearwood.info
Tue Sep 14 01:54:50 CEST 2010


On Tue, 14 Sep 2010 04:31:00 am Brian Jones wrote:
> I've been coding Python long enough that 'asking forgiveness instead
> of permission' is my first instinct, but the resulting code is
> sometimes clumsy, and I wonder if someone can suggest something I'm
> missing, or at least validate what's going on here in some way.
>
> What I'm trying to do is write a file to a directory. However, the
> directory may not exist the first time I try to write a file there,
> so I'm going to first try to write the file, and if I get an
> exception, create the directory (er, *try* to), and *then* write the
> file there. Here's my first shot at the code:

Obviously this needs to go into an independent function or method for 
ease of testing, and so that you don't have to repeat yourself each 
time you write to a file.


>         try:
>             self.save_file(picfile_fullpath, picdata)
>         except IOError as err:

Since you don't use err, there's no need for it. But since you have it, 
you might as well use it, and inspect the error code. E.g. if the error 
is permission denied, then you can bail immediately because nothing 
else will succeed either. (Well, technically it could succeed if the 
permissions change between the first failure and the subsequent attempt 
to create the directories, but you probably don't care about that.)


>             # directory doesn't exist. Try to create it.
>             try:
>                 os.makedirs(picfile_fullpath)
>             except OSError as oserr:
>                 logging.error("Can't create file path: %s (%s)" %
> (picfile_fullpath, oserr))
>             else:
>                 # Created dir, now write file.
>                 try:
>                     self.save_file(picfile_fullpath, picdata)
>                 except IOError as err:
>                     logging.error("Bailing. Couldn't save file %s
> (%s)" % (picfile_fullpath, err))
>                     return False
>
> Doesn't this seem less readable than the 'ask permission' equivalent?

Yes, but that's because the "ask permission" equivalent is fatally 
flawed -- permission can be revoked at any time, including a 
microsecond after you've been told "Yes" but before you actually get to 
save the file.

You've got more or less the right approach here, although you can 
streamline it so you're only trying to write the file once rather than 
twice. Put this in a utility function or method, where all the 
complication is hidden, just as os.makedirs hides a lot of complexity.



-- 
Steven D'Aprano


More information about the Tutor mailing list