0

假设这段代码:

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 语句来处理它们?

4

2 回答 2

4

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

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

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

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

于 2011-08-13T20:11:38.613 回答
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

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

于 2011-08-13T20:34:37.820 回答