попробуй ... кроме ... кроме ...: как избежать повторения кода - PullRequest
3 голосов
/ 18 мая 2009
  • Я бы не хотел писать errorCount += 1 более чем в одном месте.
  • Я ищу лучший способ, чем
    success = False
    try:
        ...
    else:
        success = True
    finally:
        if success:
            storage.store.commit()
        else:
            storage.store.rollback()
  • Я стараюсь избегать store.rollback() в каждом предложении кроме.

Есть идеи, как это сделать?

count = 0
successCount = 0
errorCount = 0
for row in rows:
    success = False
    count += 1
    newOrder = storage.RepeatedOrder()
    storage.store.add(newOrder)
    try:
        try:
            newOrder.customer = customers[row.customer_id]
        except KeyError:
            raise CustomerNotFoundError, (row.customer_id,)
        newOrder.nextDate = dates[row.weekday]
        _fillOrder(newOrder, row.id)
    except CustomerNotFoundError as e:
        errorCount += 1
        print u"Error: Customer not found. order_id: {0}, customer_id: {1}".format(row.id, e.id)
    except ProductNotFoundError as e:
        errorCount += 1
        print u"Error: Product not found. order_id: {0}, product_id: {1}".format(row.id, e.id)
    else:
        success = True
        successCount += 1
    finally:
        if success:
            storage.store.commit()
        else:
            storage.store.rollback()
print u"{0} of {1} repeated orders imported. {2} error(s).".format(successCount, count, errorCount)

Ответы [ 5 ]

8 голосов
/ 18 мая 2009

Это похоже на возможное применение нового оператора Python with. Он позволяет безопасно разматывать операции и освобождать ресурсы независимо от того, какой результат принес блок кода.

Читайте об этом в PEP 343

3 голосов
/ 18 мая 2009

Мое предложение - написать метод logError(), который увеличивает errorCount (делает его переменной-членом) и печатает ошибку. Поскольку ваш код исключения аналогичен, вы также можете сократить код, выполнив следующее:

try:
    # something
except (CustomerNotFoundError, ProductNotFoundError), e:
    logError(e)

Вы можете распечатать все, что хотите на основе e.

Кроме того, вам не нужно отслеживать успехи: successCount = len(rows) - errorCount

2 голосов
/ 18 мая 2009

Вы можете просто обернуть свою реализацию исключения внутри класса контейнера, специфичного для исключения, таким образом, вы также можете избежать всех этих явных вызовов печати (которые могут пригодиться после изменения интерфейса, например, при поддержке графического интерфейса пользователя), вместо будет иметь такой метод, как error (msg), который, в свою очередь, может соответствующим образом увеличить количество ошибок. Другими словами, просто установите внешний вспомогательный класс, который управляет вашими объектами обработки исключений.

0 голосов
/ 18 мая 2009

Ну, согласно этой странице, часть 7.4:

http://docs.python.org/reference/compound_stmts.html

Это возможно с python ver. > = 2.6. Я имею в виду, попробуй .. кроме .. наконец, строительство.

0 голосов
/ 18 мая 2009

Если вам нравится накапливать ошибки, почему вы не накапливаете ошибки? Если вы помещаете сообщения об ошибках в список, размер списка дает необходимую вам информацию. Вы даже можете что-то постобработать. Вы можете легко решить, произошла ли ошибка, и печать вызывается только в одном месте

...