【问题标题】:How to handle exceptions in python using the `with` statement in python?如何使用python中的`with`语句处理python中的异常?
【发布时间】:2011-08-13 20:03:23
【问题描述】:

假设这段代码:

connection = get_some_connection() # maybe from oursql
with connection.cursor() as cursor:
    cursor.execute('some query')

我了解cursor.close() 完成后会自动执行。例外情况如何?我必须把它们放在里面吗?

connection = get_some_connection() # maybe from oursql
with connection.cursor() as cursor:
    try:
        cursor.execute('some query')
    except IntegrityError, e:
        # handle exceoption

或者有没有更好的方法来使用 with 语句来处理它们?

【问题讨论】:

    标签: python exception-handling with-statement


    【解决方案1】:

    with x as y: z() 基本上是语法糖:

    y = x
    y.__enter__()
    try:
        z()
    finally:
        if y.__exit__: y.__exit__()
    

    这并不完全准确,但这就是它的要点。请注意,如果抛出异常,__exit__() 将被传递异常信息(请参阅the docs),因此您可以通过这种方式“处理”异常,但这不会阻止异常被抛出调用堆栈。

    如果你想优雅地处理异常并消费它,你需要使用try/catch 块。它可以在 with 块内部或外部,只要在引发异常时 try 块处于活动状态。

    【讨论】:

    • 由于异常是如何传播的,您能不能也将try/catch 立即放在 with 块之外? ;)
    【解决方案2】:

    oursql的特殊情况下,

    with some_connection.cursor() as cursor:
        do_something_with(cursor)
    

    等价于

    cursor = some_connection.cursor()
    try:
        do_something_with(cursor)
    except:
        some_connection.rollback()
        raise
    else:
        some_connection.commit()
    finally:
        cursor.close()
    

    如您所见,with 语句的作用取决于上下文管理器(例如 some_connection.cursor()`)。

    with connection.cursor() as cursor:
        try:
            cursor.execute('some query')
        except IntegrityError as e:
            # handle exception
    

    可能是也可能不是处理IntegrityError 的正确方法——您可能希望在某个外部范围内处理 IntegrityError。

    例如,如果您有一些记录查询的通用函数,例如

    def log_query(query):
        logger.info(query)
        with connection.cursor() as cursor:
            cursor.execute(query)
    
    try:
        log_query(query)
    except IntegrityError as err:
         # handler error
    

    您可能不想在 log_query 中处理 IntegrityErrors,而是在稍后阶段处理。

    【讨论】:

    • 请注意,如果您确实在内部处理了错误,并且不重新引发,那么您最好以与光标与时发生的some_connection.commit() 兼容的方式处理它 -块清理:)
    猜你喜欢
    • 2015-10-24
    • 2014-02-15
    • 2016-04-21
    • 2010-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    相关资源
    最近更新 更多