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> 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 > > -- Brian K. Jones My Blog http://www.protocolostomy.com Follow me http://twitter.com/bkjones
_______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor