<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html; charset=ISO-8859-1"
 http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#ffffff">
On 13/09/10 20:12, Brian Jones wrote:
<blockquote
 cite="mid:AANLkTimcaJJ69DkjFmH_pbT0PxzxwF9n9COK4-tdv-C-@mail.gmail.com"
 type="cite">Thanks for the replies so far. One thing that's probably
relevant: once a directory is created, I can expect to write a couple
of hundred files to it, so doing a 'try os.makedirs' right off the bat
strikes me as coding for the *least* common case instead of the *most*
common (which is that the directory exists and the file write
succeeds). If this were a one-off file write.... well then things get
easier, but I'd like to avoid attempting a makedirs 100 times when 99
of those times I know it'll give me an error.&nbsp;
  <div><br>
  </div>
  <div>brian<br>
  <br>
  <div class="gmail_quote">On Mon, Sep 13, 2010 at 3:07 PM, Evert Rol <span
 dir="ltr">&lt;<a moz-do-not-send="true"
 href="mailto:evert.rol@gmail.com">evert.rol@gmail.com</a>&gt;</span>
wrote:<br>
  <blockquote class="gmail_quote"
 style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
    <div class="im">&gt; 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.<br>
&gt;<br>
&gt; 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.<br>
    <br>
    </div>
That would work.<br>
Though I would just try to create the error directory first. If that
fails, I check the error message/code in the except clause: if it
indicates the directory already exists, I pass the exception, otherwise
reraise it.<br>
Then I continue with creating the file within the directory I now am
certain of exists.<br>
Note 1: certain is only half: some other process could remove the
directory in the split second between my code creating it and my code
creating the file. If you think that could happen, you'll need to look
at the other ways to do this.<br>
Note 2: the directory can exist, but not have write access to your
process. So between the try-except for creating a directory and the
try-except for creating a file, you may put in a try-except for chmod.
Of course, if you're not the owner, both the chmod and file creation
will fail (I'm assuming some *nix platform here, btw).<br>
    <div class="im"><br>
&gt; Here's my first shot at the code:<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; try:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.save_file(picfile_fullpath, picdata)<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; except IOError as err:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # directory doesn't exist. Try to create it.<br>
    <br>
    </div>
Careful: you're not checking the actually error given by the exception.
There may be more than one reason that the file can't be created
(examples: the permissions mentioned above, or some file creation limit
in a directory).<br>
    <div class="im"><br>
    <br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os.makedirs(picfile_fullpath)<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; except OSError as oserr:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logging.error("Can't create file path: %s (%s)" %
(picfile_fullpath, oserr))<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Created dir, now write file.<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.save_file(picfile_fullpath, picdata)<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; except IOError as err:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logging.error("Bailing. Couldn't save file %s
(%s)" % (picfile_fullpath, err))<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return False<br>
&gt;<br>
&gt; 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.<br>
    <br>
    </div>
One of the things I once read (but I forgot where) on this issue, is
the usual "it depends". It depends whether you except that often, the
directory doesn't exist and the file can't directly be created. In that
case, if may be quicker to ask permission first (simple if-statement).
If you expect that in general, you can immediately create the file
within the directory (so an exception is unlikely to occur), then use a
try-except clause.<br>
But don't take my word for it; I'd be curious what others on this list
say about this.<br>
    <div class="im"><br>
    <br>
&gt;<br>
&gt; 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.<br>
&gt;<br>
&gt; Is there a clean sort of pattern to apply in instances like this?<br>
    <br>
    </div>
I guess not, though readability of code is an important thing to
consider. In this case, I don't find the correctly unreadable, but at
some point, these things do tend to get out of hand and you're better
off coding it differently (perhaps even using functions).<br>
    <font color="#888888"><br>
    <br>
&nbsp;Evert<br>
    <br>
    </font></blockquote>
  </div>
  </div>
</blockquote>
Well surely then you just check the directory first with a try:
os.makedirs. Then your try: self.savefile for each file.<br>
<br>
</body>
</html>