首页 > 解决方案 > try/except 和上下文管理器

问题描述

我正在尝试使我的 try/except 块尽可能小。但是,我不知道如何将其与可能很长的with块相协调:

try:
    with db.connect() as connection:
        # many lines interacting with the database
        # and more lines
        # and yet more lines

except ConnectionError:

有没有办法写 try/except 所以它不是那么长?

我想我可以将大部分代码重新组织成一个单独的函数:

try:
    with db.connect() as connection:
        do_stuff(connection)
except ConnectionError:

...但似乎应该有一种方法可以在更少的行中做到这一点。

标签: pythonexception

解决方案


您实际上不必将with语句放在try语句中, ifdb.connect是唯一可以引发ConnectionError. 如果出现连接错误,则没有要关闭的连接。

try:
    connection = db.connect()
except ConnectionError:
    ...

with connection:
    ...

声明关心的不是对db.connect自身的调用;这是对andwith的调用。connection.__enter__connection.__exit__

根据您的操作,可能应该保护ConnectionError该语句以避免尝试使用未定义的名称。withconnection


connection如果您不喜欢在分配它和with语句之间做某事的想法,您可以使用 anExitStack立即进入上下文。例如,

from contextlib import ExitStack


with ExitStack() as es:
    try:
        connection = es.enter_context(db.connect())
    except ConnectionError:
        ...

    # do stuff with the connection

推荐阅读