try... except... except... : 如何避免重复代码

4 投票
5 回答
1942 浏览
提问于 2025-04-15 11:40
  • 我想避免在多个地方写 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 个回答

2

你可以把你的异常处理代码放在一个专门的容器类里,这样就可以避免到处写打印信息的代码(这在你以后改接口,比如支持图形界面时,会很有用)。你只需要一个像 error(msg) 这样的函数,它可以自动增加错误计数。换句话说,就是建立一个外部的辅助类,专门来管理你的异常处理。

3

我建议你写一个叫做 logError() 的方法,这个方法可以增加一个叫 errorCount 的变量(把它设为类的成员变量),并且打印出错误信息。因为你的异常处理代码很相似,所以你可以通过这样做来简化你的代码:

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

你可以根据 e 的内容打印出你想要的任何信息。

另外,你不需要去记录成功的次数:可以用 successCount = len(rows) - errorCount 来计算成功的数量。

8

这看起来像是Python新出的with语句的一个可能用法。这个语句可以帮助我们安全地处理操作和释放资源,不管代码块的执行结果如何。

想了解更多,可以看看PEP 343

撰写回答