Подтвердить что ты не робот

Часто повторяется try/except в Python

Во-первых, я не уверен, что мой подход правильный, поэтому я открыт для различных предложений.

Если аргументы try/except часто повторяются в коде, есть ли какие-либо хорошие способы их сокращения или избежать их полной записи?

try:
    # Do similar thing
    os.remove('/my/file')
except OSError, e:
    # Same exception handing
    pass

try:
    # Do similar thing
    os.chmod('/other/file', 0700)
except OSError, e:
    #Same exception handling
    pass

Например, для действий одной строки вы можете определить оболочку обработки исключений, а затем передать лямбда-функцию:

def may_exist(func):
    "Work with file which you are not sure if exists."""
    try:
        func()
    except OSError, e:
        # Same exception handling
        pass

may_exist(lambda: os.remove('/my/file'))
may_exist(lambda: os.chmod('/other/file', 0700))

Разве это "решение" просто делает вещи менее ясными? Должен ли я просто полностью выписать все инструкции try/except?

4b9b3361

Ответ 1

Лучший способ абстрагирования обработки исключений - с менеджером контекста:

from contextlib import contextmanager
@contextmanager
def common_handling():
    try:
        yield
    finally:
        # whatever your common handling is

то

with common_handling():
    os.remove('/my/file')

with common_handling():
    os.chmod('/other/file', 0700)

Это имеет то преимущество, что вы можете поместить полные операторы и более одного из них в каждый блок common_handling.

Имейте в виду, что ваша потребность использовать одну и ту же обработку снова и снова кажется слишком похожей на чрезмерные обработки исключений. Вы уверены, что вам нужно это сделать?

Ответ 2

Возможно, было бы лучше сделать may_exist декоратором:

from functools import wraps
def may_exist(func):
   @wraps(func):
   def wrapper(*args, **kwds):
       try:
           return func(*args, **kwds)
       except OSError:
           pass
   return wrapper

Тогда вы можете либо сделать:

may_exist(os.remove)('/my/file')
may_exist(os.chmod)('/other/file', 0700)

для одноразового вызова или:

remove_if_exists = may_exist(os.remove)
...
remove_if_exists('somefile')

если вы используете его много.

Ответ 3

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

def may_exist(func, *args):
    "Work with file which you are not sure if exists."""
    try:
        func(args)
    except OSError, e:
        # Same exception handling
        pass

may_exist(os.remove, '/my/file')
may_exist(os.chmod, '/other/file', '0700')

Ответ 4

Что-то вроде этой работы:

def may_exist(func, *func_args):
    try:
        func(*func_args)
    except OSError as e:
        pass