根据条件使用不同的上下文管理器

2024-09-28 01:31:21 发布

您现在位置:Python中文网/ 问答频道 /正文

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

示例:

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

一种方法是将...包装成一个函数,但在我的例子中这可能不太方便。还有别的可能吗?你知道吗


Tags: 示例管理器ifaswithargssomecondition
3条回答

我们可以疯狂地利用这样一个事实:__enter____exit__都只是方法,它们是在原始对象(不是__enter__返回的对象)中调用的:

class WrapperContext:

 def __init__(self, condition):
     if condition:
         self.real_context = ContextA()
     else:
         self.real_context = ContextB()

 def __enter__(self):
     return self.real_context.__enter__()

 def __exit__(self):
     return self.real_context.__exit__()

像这样使用:

 with WrapperContext(condition) as obj:

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

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

with cm as contex:
        ... # some block

上述内容可以很容易地扩展到三个可能的上下文管理器,等等。例如,您还可以决定在“进入”上下文之前首先“修补”上下文管理器。你知道吗

尽管像with foo() as bar:这样的模式很常见,但实际上Python只是计算foo(),获取该元素,并调用对象上的.__enter__()。该方法的结果存储在bar中。你知道吗

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

那。。。你知道吗

with ContextManager(**args) if some_condition else OtherContextManager(**other_args) as contex:
    ... # some block

。。。?你知道吗

相关问题 更多 >

    热门问题