2016-12-14 4 views
1

Я написал сценарий python, который хочет записывать журналы в файл на /var/log/myapp.log. Однако на некоторых платформах этого не существует, или у нас может не быть разрешения на это. В этом случае я хотел бы попробовать написать где-нибудь еще.Открытие другого файла на IOError

def get_logfile_handler(): 
    log_file_handler = None 
    log_paths = ['/var/log/myapp.log', './myapp.log'] 
    try: 
     log_file_handler = logging.FileHandler(log_paths[0]) 
    except IOError: 
     log_file_handler = logging.FileHandler(log_paths[1]) 

    return log_file_handler 

Приведенный выше код может работать, но это, кажется, далеко от элегантности - в частности, попробовать другой файл в качестве части обработки исключений кажется неправильным. Это может просто вызвать еще одно исключение!

В идеале для этого потребуется произвольный список путей, а не только два. Есть ли элегантный способ написать это?

+0

Я считаю, что модуль 'tempfile' может решить проблему https://docs.python.org/3.5/library/tempfile.html –

+2

Завершите свои логические пути до тех пор, пока не получите тот, который не вызывает' IOError' , Если вы дойдете до конца списка, не найдя действительного имени, войдите в stderr или умрите с соответствующим сообщением об ошибке. –

ответ

1

вы можете просто использовать цикл, такие как:

def get_logfile_handler(): 
    log_file_handler = None 
    log_paths = ['/var/log/myapp.log', './myapp.log'] 
    for log_path in log_paths: 
     try: 
      return logging.FileHandler(log_path) 
     except IOError: 
      pass 

    raise Exception("Cannot open log file!") 

HTH

+0

'return logging.FileHandler (log_path)' сохранит несколько строк кода и вернет первый действительный обработчик вместо последнего. –

+0

@KlausD. точно редактирование, которое я делал ☺ – zmo

0
def get_logfile_handler(log_files): 
    log_file_handler = None 
    for path in log_files: 
     try: 
      log_file_handler = logging.FileHandler(path) 
      break 
     except IOError: 
      pass 

    return log_file_handler 

Это может решить вашу проблему. Вы можете определить локально/глобально вместо передачи в качестве параметра.

0

В качестве возможного решения, если вы хотите избежать обработки исключений, вы можете проверить операционную систему, на которой вы находитесь, с помощью модуля platform, а затем выбрать нужный путь. Затем вы можете использовать модули os и stat для проверки разрешений.

import platform 
import os 
import stat 

... 

#the logic goes here 

... 
1

Существует, как замечает @ PM-2 комментарий, не нужно ссылаться на каждый возможный путь индивидуально. Вы могли бы попробовать что-то вроде этого:

def getlogfile_handler(): 
    log_file_handler = None 
    log_paths = ('/var/log/myapp.log', './myapp.log') # and more 
    for log_path in log_paths: 
     try: 
      log_file_handler = logging.FileHandler(log_path) 
      break 
     except IOError: 
      continue 
    else: 
     raise ValueError("No log path available") 
    return log_file_handler 

Предложения else обрабатывает случай, когда цикл завершается, не найдя подходящее значение log_path. Если цикл прерывается раньше (и только после этого), выполняется оператор return.

Совершенно нормально использовать исключения для целей потока управления, такие как: случаи исключительны, но они не являются ошибками - единственная реальная ошибка возникает, когда путь не найден, и в этом случае код вызывает свое собственное исключение, вызывающий может поймать, если он так выбирает.

Смежные вопросы