3

I'm trying to execute a statement, but if it fails I want to execute the except statement and after I want to execute the try again. I know I can use loops, but I'm looking for a more elegant solution.

In my use case I try to save a file to a folder but if I get the FileNotFoundError I want to create the folder in the except and go to the try again.

from pathlib import Path
import os

folder = Path('folder')
df = [a,b,c]

try:
    df.to_feather(folder / 'abc.ftr')
except:
    os.makedirs(folder)
    df.to_feather(folder / 'abc.ftr')

But in this case I would repeat the df.to_feather(folder / 'abc.ftr') statement. This get's annoying if the statement gets larger and I want to refrain for building a function for this.

Another way could be:

if folder not in os.listdir():
    os.makedirs(folder)

df.to_feather(folder / 'abc.ftr')

Would this be the 'proper' way to tackle this?

Hestaron
  • 190
  • 1
  • 8
  • Does this answer your question? [Python pathlib make directories if they don’t exist](https://stackoverflow.com/questions/50110800/python-pathlib-make-directories-if-they-don-t-exist) – Nathan Dec 07 '21 at 09:50
  • @Nathan Not a duplicate! – jtlz2 Dec 07 '21 at 10:03
  • Related: https://stackoverflow.com/questions/10594113/bad-idea-to-catch-all-exceptions-in-python – moooeeeep Dec 07 '21 at 10:08
  • 1
    Your statement is contradictory: "This get's annoying if the statement gets larger and I want to refrain for building a function for this." - breaking down a problem in to smaller parts (functions in this instance) is a way of reducing complexity and reusing code to avoid duplication. Why would you _not_ want to do that? – Tony Dec 07 '21 at 10:09
  • Does this answer your question? [How can I safely create a nested directory in Python?](https://stackoverflow.com/questions/273192/how-can-i-safely-create-a-nested-directory-in-python) – Tony Dec 07 '21 at 10:26

2 Answers2

3

Since python3.2 os.makedirs has optional exist_ok argument, which by default is False. When set True and os.makedirs is instructed to create catalog(s) which is(are) already existing it is no-operation. Thus in place of

if folder not in os.listdir():
    os.makedirs(folder)

df.to_feather(folder / 'abc.ftr')

you can just do

os.makedirs(folder, exist_ok=True)
df.to_feather(folder / 'abc.ftr')
Daweo
  • 31,313
  • 3
  • 12
  • 25
  • 1
    Although this answers the particular case of the user, it misses the general answer to the question about how to try something and if it fails try it again after doing something in the middle to remedy the first fail. –  Dec 07 '21 at 10:02
  • @SembeiNorimaki - Just because someone asks how to do something does not make it the best way of achieving the desired result. Although the question is asking about retrying in the event of an exception, it is generally better to avoid exceptions in the first place. The question does also go on to ask if checking for, and creating the missing folder, would "be the 'proper' way to tackle this?". So I think Daweo's answer is perfectly valid. – Tony Dec 07 '21 at 10:13
  • @Tony " it is generally better to avoid exceptions in the first place." why? in Python? what happened to EAFP? –  Dec 07 '21 at 10:33
  • @athing - true, and I admit I come from a C/C++ background where exceptions were more expensive computationally :) but that doesn't make them free in Python either. There are cases when checking first is more efficient if you expect the operation to fail more often than not. But in this particular instance, when interacting with the file system, it's a solved problem, as described in this answer. – Tony Dec 07 '21 at 18:29
2

To answer the question in the title, you can do this recursively:

def do_stuff(x):
    try:
        stuff(x)
    except SpecificException:
        other_stuff(x)
        do_stuff(x)

If you want to create a file, you can just use:

pathlib.Path('/tmp/sub1/sub2').mkdir(parents=True, exist_ok=True)
Nathan
  • 3,558
  • 1
  • 18
  • 38
  • 2
    It would be wise to check what caused the exception and only call `do_stuff` again if the fault can be rectified, otherwise you'll recurse until the stack overflows. – Tony Dec 07 '21 at 10:25
  • bare except is dangerous –  Dec 07 '21 at 10:34