Часто повторяемые попытки / за исключением Python - PullRequest
20 голосов
/ 18 августа 2011

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

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

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 / кроме?

Ответы [ 4 ]

25 голосов
/ 18 августа 2011

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

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.

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

4 голосов
/ 18 августа 2011

Возможно, было бы чище сделать 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')

если вы часто его используете.

2 голосов
/ 18 августа 2011

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

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')
1 голос
/ 18 августа 2011

Хотелось бы что-то вроде этой работы:

def may_exist(func, *func_args):
    try:
        func(*func_args)
    except OSError as e:
        pass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...