[Tutor] What's the best way to ask forgiveness here?
Adam Bark
adam.jtm30 at gmail.com
Mon Sep 13 21:07:33 CEST 2010
On 13/09/10 19:31, 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:
>
> try:
> self.save_file(picfile_fullpath, picdata)
> except IOError as err:
> # 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?
> I think it does, but in this case asking permission for every single
> operation when the dir will only need to be created a single time (and
> then may be written to several hundred times) is pretty wasteful.
>
> I suppose I could set some sentinel variable and check for it in a
> while loop, but then I need some other scaffolding code to make sure I
> don't infinitely loop trying to create the directory, and probably
> some other stuff I'm forgetting, so it strikes me as being just as messy.
>
> Is there a clean sort of pattern to apply in instances like this?
>
> Thanks.
> brian
How about something like this?
try:
os.makedirs(picfile_fullpath)
self.save_file(picfile_fullpath, picdata)
except IOError, OSError as err:
if type(err) is OSError:
logging.error("Can't create file path: %s (%s)" %
(picfile_fullpath, oserr))
try:
self.save_file(picfile_fullpath, picdata)
except IOError:
logging.error("Bailing. Couldn't save file %s (%s)" %
(picfile_fullpath, err))
else:
logging.error("Bailing. Couldn't save file %s (%s)" %
(picfile_fullpath, err))
This saves you one try except and the else although it adds an if else.
Either way it's not as far nested.
I just thought up another way that just takes two try excepts:
try:
try:
os.makedirs(picfile_fullpath)
self.save_file(picfile_fullpath, picdata)
except OSError as oserr:
logging.error("Can't create file path: %s (%s)" %
(picfile_fullpath, oserr))
self.save_file(picfile_fullpath, picdata)
except IOError as err:
logging.error("Bailing. Couldn't save file %s (%s)" %
(picfile_fullpath, err))
return False
HTH
More information about the Tutor
mailing list