On 13/09/10 20:12, Brian Jones wrote:
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.
brian
On Mon, Sep 13, 2010 at 3:07 PM, Evert Rol <evert....@gmail.com
<mailto:evert....@gmail.com>> 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.
That would work.
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.
Then I continue with creating the file within the directory I now
am certain of exists.
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.
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).
> 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.
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).
> 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.
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.
But don't take my word for it; I'd be curious what others on this
list say about this.
>
> 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?
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).
Evert
Well surely then you just check the directory first with a try:
os.makedirs. Then your try: self.savefile for each file.
_______________________________________________
Tutor maillist - Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor