[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