python 2.x: условно перехват исключений (игнорируйте изящную очистку, если файл отсутствует) - PullRequest
0 голосов
/ 15 мая 2019

У меня есть сценарий, который очищает журналы старше 14 дней в общей папке. Теперь этот скрипт может запускаться одновременно с другого хоста. В конкретной ситуации, если два или более хоста пытаются очистить один и тот же файл, удастся выполнить только один, а все остальные выдают ошибку «Нет такого файла или каталога». Как я могу обновить код, чтобы Проигнорировать изящную очистку, если файл внезапно пропадает. Ниже приведена часть кода, которая выполняет очистку. count отслеживает количество удаленных файлов.

if os.stat(filename).st_mtime < current_time - 14 * 86400:
    try:
       os.remove(filename)
       count += 1
    except:
       logger.warning("Not able to delete the file %s" % filename)

Один из способов - «передать» исключение, если файл не существует, но продолжать регистрировать предупреждение, если вы не можете удалить файл. Как включить это условие.

Ответы [ 2 ]

1 голос
/ 15 мая 2019

Предложение except без списка исключений (типов) является универсальным: его легко настроить, но сложно использовать.Здесь вы должны специально поймать (и проигнорировать) FileNotFoundError и зарегистрировать любое другое исключение:

try:
   if os.stat(filename).st_mtime < current_time - 14 * 86400:
      os.remove(filename)
      count += 1
except FileNotFoundError:
   pass  # file has already been deleted: all is fine
except:
   logger.warning("Not able to delete the file %s" % filename)

Выше было для Python 3, так как вы используете Python 2, вы можете проверять только OSError изатем управляйте его атрибутом errno:

try:
   if os.stat(filename).st_mtime < current_time - 14 * 86400:
      os.remove(filename)
      count += 1
except OSError as e:
   if e.errno != errno.ENOENT:
      # do not log if file has already been deleted
      logger.warning("Not able to delete the file %s" % filename)
except:
   logger.warning("Not able to delete the file %s" % filename)
1 голос
/ 15 мая 2019

Как @Mark предлагает заранее проверить, существует ли файл, а затем удалить его, но в таком подходе все еще есть потенциальное состояние гонки. Это может произойти между экземплярами скрипта после os.stat и до os.remove. Перемещение всего кода, вызывающего ошибки на try / except, должно сработать. Однако, как я понимаю, существует проблема с регистрацией правдивого сообщения. Дополнительный флаг attempted_delete должен помочь с этим:

attempted_delete = False
try:
    if os.stat(filename).st_mtime < current_time - 14 * 86400:
         os.remove(filename)
         count += 1
         attempted_delete = True
except:
     if attempted_delete:
         logger.warning("Not able to delete the file %s" % filename)
...