Часто повторяется 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?
Ответы
Ответ 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