根据情况使用不同的上下文管理器

che*_*ate 5 python with-statement contextmanager python-3.x

是否可以根据某些条件使用不同的上下文管理器执行单个块?

例子:

if some_condition:
    with ContextManager(**args) as contex:
        ... # some block
else:
    with OtherContextManager(**other_args) as contex:
        ... # the same block
Run Code Online (Sandbox Code Playgroud)

一种方法是包装...到一个函数中,但这对我来说可能不太方便。还有另一种可能吗?

Wil*_*sem 7

您可以将构造的对象存储在变量中,例如:

if some_condition:
    cm = ContextManager(**args)
else:
    cm = OtherContextManager(**other_args)

with cm as contex:
        ... # some block
Run Code Online (Sandbox Code Playgroud)

上面的内容可以轻松扩展到三个可能的上下文管理器等。您还可以决定例如在“进入”上下文之前首先“修补”上下文管理器。

虽然像 之类的模式很常见with foo() as bar:,但实际上 Python 只是简单地计算foo()、获取该元素并调用.__enter__()该对象。该方法的结果存储在bar.

foo() 所以call没有什么“特别”的,您可以在左侧使用任何类型的对象。因此,您可以将if-else逻辑封装在单独的函数中,并返回上下文管理器,然后使用变量,或将上下文管理器作为参数传递。只要你在with语句中使用它,Python就会在幕后调用.__enter__(..)and 。.__exit__(..)