假设我有一个类,它将生成一个线程并实现.__enter__
和.__exit__
,因此我可以这样使用它:
with SomeAsyncTask(params) as t:
# do stuff with `t`
t.thread.start()
t.thread.join()
.__exit__
可能出于清理目的执行某些操作(即删除临时文件等)
在我有一个SomeAsyncTask
列表之前,这一切都很好。你知道吗
list_of_async_task_params = [params1, params2, ...]
我应该如何在列表中使用with
?我希望这样:
with [SomeAsyncTask(params) for params in list_of_async_task_params] as tasks:
# do stuff with `tasks`
for task in tasks:
task.thread.start()
for task in tasks:
task.thread.join()
注意:不知何故,我忽略了这样一个事实,即您的
Thread
子类本身也是一个上下文管理器,因此下面的代码不会做出这种假设。然而,当使用更“通用”类型的线程时(使用contextlib.ExitStack
之类的线程将不是一个选项),它可能会有所帮助。你知道吗你的问题是有点轻的细节,所以我编了一些,但这可能是接近你想要的。它定义了一个
AsyncTaskListContextManager
类,该类具有支持上下文管理器协议所需的__enter__()
和__exit__()
方法(以及相关的with
语句)。你知道吗输出:
我想^{} 正是你要找的。这是一种将不确定数量的上下文管理器安全地组合到一个上下文管理器中的方法(这样在输入一个上下文管理器时出现异常不会导致它跳过已经成功输入的上下文管理器)。你知道吗
文件中的例子很有启发性:
这可以很容易地适应您的“希望”代码:
@martineau答案应该有用。这里有一个更通用的方法,应该适用于其他情况。请注意,
__exit__()
中不处理异常。如果一个__exit__()
函数失败,其余的函数将不会被调用。通用解决方案可能会抛出聚合异常并允许您处理它。另一种情况是当您的第二个管理器的__enter__()
方法抛出异常时。在这种情况下,不会调用第一个管理器的__exit__()
。你知道吗然后可以像在你的问题中那样使用:
相关问题 更多 >
编程相关推荐