Lat*_*der 6 contextmanager python-3.x
我需要创建一个上下文管理器,当满足某些条件时,可以强制它提前退出.
更多细节:
上下文管理器需要处理检查/锁定/释放资源.在__enter__,上下文管理器需要检查资源是否被锁定.如果是,我想在__exit__不执行上下文中的代码的情况下调用.否则,上下文管理器获取资源,执行上下文代码,并清理资源__exit__.
它可能看起来像这样:
class my_context_manager:
def __enter__(self):
if resource_locked():
self.__exit__(None, ResourceLockedException(), None)
else:
acquire_resource()
def __exit__(self, *exc_info):
if not isinstance(exc_info[1], ResourceLockedException):
release_resource()
else:
log.warn("Resource already in use.")
Run Code Online (Sandbox Code Playgroud)
但是,上面的代码实际上并不起作用,因为调用__exit__内部__enter__并不会阻止上下文中的代码被执行.
或者,我可以ResourceLockedException从内部抛出__enter__,但之后__exit__不会被调用,因为异常将从上下文管理器本身抛出.我希望能够捕获异常,记录警告,如果资源被锁定则不输入上下文.
这归结为找到一些早期关闭上下文的方法,因此__exit__调用它并且不执行上下文代码.有没有办法调整上述任何一个想法来做到这一点?或者还有另一种方式吗?
是的,你不能__exit__像这样手动调用。另一种选择就是简单地raise处理异常并让另一个构造来管理它。您可以使用try-except或启动另一个上下文管理器来记录这些:
from contextlib import contextmanager
@contextmanager
def log_exception():
try:
yield
except ResourceLockedException as e:
log.warn(e)
Run Code Online (Sandbox Code Playgroud)
并将原来的上下文管理器更改为:
class my_context_manager:
def __enter__(self):
if True:
raise ResourceLockedException("Resource already in use")
acquire_resource()
def __exit__(self):
release_resource()
Run Code Online (Sandbox Code Playgroud)
并用以下方式调用它:
with log_exception(), my_context_manager():
# do things when resource acquired.
Run Code Online (Sandbox Code Playgroud)
当然,您可以简单地使用 atry-except并嵌套with在其中,或者使用一个if子句。
| 归档时间: |
|
| 查看次数: |
917 次 |
| 最近记录: |