@vlzemtsov

Как лучше всего обрабатывать ошибки в python?

Добрый день.

Для развития пишу небольшую программу на python и возник такой вопрос:
Как лучше всего обрабатывать возможные ошибки?

Суть в том, что в различных частях программы, (в различных функциях, например), я хочу добавить обработку возможных ошибок.
Попробовал это сделать с помощью конструкции try: (except:), в которой если код не выполнился - я записываю в /var/log/*program*/file.log - причину ошибки, которую сам и указываю, однако это очень сильно нагружает код.

Есть возможность сделать это как-нибудь поизящнее, что ли?
  • Вопрос задан
  • 506 просмотров
Решения вопроса 2
Советую вам посмотреть в сторону декораторов. Полезно будет как для решения задачи, так и для общего ознакомления с синтаксическими возможностями языка.
Дам пример самого простого декоратора, единственная функция которого "тихо" логгировать любой exception:
import logging


LOG = logging.getLogger(__name__)


def handle_silently(function):
    def wrapped(*args, **kwargs): 
        result = None
        try:
            result = function(*args, **kwargs)
        except Exception as e:
            LOG.error(
                '{}(*{}, **{}) failed with exception {}'.format(
                    function.__name__, repr(args), repr(kwargs), repr(e) 
                 )
            )
        return result
    return wrapped


@handle_silently
def some_function(test):
    return test / 0

Конструкция @handle_silently заменит вашу функцию some_function на функцию wrapped.
Механика работы wrapped является, скорее, антипаттерном, поскольку замалчивать exception совсем и тем более отдавать вместо него None - это гарантированный способ выстрелить себе в ногу. Это просто пример, в боевом проекте я бы посоветовал ререйзить (LOG.error(...); raise) ошибку в декораторе и обрабатывать несредственно в месте вызова функции (логгирование, естественно, можно и оставить).
Для затравки и для демонстрации того, как это может быть полезно - декотораторы могут быть параметрическими (достигается это путём создания фабрики декораторов):
def decorators_fabric(handler_function):
    def decorator(function):
        def wrapped(*args, **kwargs):
            handler_function(function.__name__, repr(args), repr(kwargs))
            return function(*args, **kwargs)
        return wrapped
    return decorator


@decorators_fabric(print)
def my_test_function(arg1, arg2):
    return arg1 * arg2
Ответ написан
Комментировать
adugin
@adugin Куратор тега Python
Основная конструкция:
try:
    ...
except SomeException as e:
    ...
except AnotherException as e:
    ...
except (ThirdException, FourthException):
    ...
else:
    ...
finally:
    ...

Для явного замалчивания ошибок:
from contextlib import suppress

with suppress(SomeException):
    ...

Это эквивалентно следующей конструкции:
try:
    ...
except SomeException:
    pass


Для записи логов используйте модуль logging.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
dimonchik2013
@dimonchik2013
non progredi est regredi
finally еще освой, хорошо соединения закрывать ))

ну и лог, надеюсь, модулем logging пишешь, не принтами?
Ответ написан
Комментировать
Sly_tom_cat
@Sly_tom_cat
.
В пойманном exception есть вся информация по ошибке. Просто нужно выбрать что именно из значений exception полезно/нужно/хочется записать в лог, но можно и целиком exception туда в str преобразованный вывести.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы