根据条件使用不同的上下文管理器
Using different context managers depending on condition
是否可以根据某些条件使用不同的上下文管理器执行单个块?
示例:
if some_condition:
with ContextManager(**args) as contex:
... # some block
else:
with OtherContextManager(**other_args) as contex:
... # the same block
一种方法是将 ...
包装到一个函数中,但这对我来说可能不太方便。还有其他可能吗?
您可以将构建的对象存储在变量中,例如:
if some_condition:
cm = ContextManager(**args)
else:
cm = OtherContextManager(**other_args)
with cm as contex:
... # some block
以上内容可以很容易地扩展到三个可能的上下文管理器等。例如,您还可以决定先 "patch" 上下文管理器,然后再 "entering" 上下文。
虽然经常看到像 with foo() as bar:
这样的模式,但实际上 Python 只是计算 foo()
,获取该元素,然后在对象上调用 .__enter__()
.该方法的结果存储在 bar
.
中
所以foo()
调用没有什么"special",你可以在左边使用任何类型的对象。因此,您可以将 if
-else
逻辑封装在一个单独的函数中,并将 return 上下文管理器封装起来,然后使用变量,或将上下文管理器作为参数传递。只要你在 with
语句中使用它,Python 就会在幕后调用 .__enter__(..)
和 .__exit__(..)
。
怎么样...
with ContextManager(**args) if some_condition else OtherContextManager(**other_args) as contex:
... # some block
...?
我们可以疯狂地利用 __enter__
和 __exit__
都只是方法并且它们在原始对象中被调用的事实(而不是 [= 返回的对象) 12=]):
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:
with ContextManager(**args) as contex:
... # some block
else:
with OtherContextManager(**other_args) as contex:
... # the same block
一种方法是将 ...
包装到一个函数中,但这对我来说可能不太方便。还有其他可能吗?
您可以将构建的对象存储在变量中,例如:
if some_condition:
cm = ContextManager(**args)
else:
cm = OtherContextManager(**other_args)
with cm as contex:
... # some block
以上内容可以很容易地扩展到三个可能的上下文管理器等。例如,您还可以决定先 "patch" 上下文管理器,然后再 "entering" 上下文。
虽然经常看到像 with foo() as bar:
这样的模式,但实际上 Python 只是计算 foo()
,获取该元素,然后在对象上调用 .__enter__()
.该方法的结果存储在 bar
.
所以foo()
调用没有什么"special",你可以在左边使用任何类型的对象。因此,您可以将 if
-else
逻辑封装在一个单独的函数中,并将 return 上下文管理器封装起来,然后使用变量,或将上下文管理器作为参数传递。只要你在 with
语句中使用它,Python 就会在幕后调用 .__enter__(..)
和 .__exit__(..)
。
怎么样...
with ContextManager(**args) if some_condition else OtherContextManager(**other_args) as contex:
... # some block
...?
我们可以疯狂地利用 __enter__
和 __exit__
都只是方法并且它们在原始对象中被调用的事实(而不是 [= 返回的对象) 12=]):
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: