嵌套一个对象的多个上下文管理器函数

Nesting multiple context manager functions of an object

我正在使用 python 2.7(迁移尚未完成)并尝试构建一个聚合 class(集群),它提供与其单个项目相同的上下文管理器功能(保留)(节点)。理想情况下,我希望在不重构包含对象节点的上下文管理器功能的情况下执行此操作。如果它有单独的 enter() 和 exit() 方法,也许我会在 Cluster.reserved() 上下文管理器函数中直接调用它们。但我认为可能有更优雅的方式来做到这一点。我尝试使用 ExitStack 执行以下代码:

from contextlib import contextmanager
from contextlib2 import ExitStack

class Node:
    def __init__(self, id):
        self._id = id

    @contextmanager
    def reserved(self):
        print("Node {} reserved".format(self._id))
        try:
            yield
        except:
            print("Exception while handling node")
        finally:
            print("Node released")

    def reserve(self):
        print("Node {} reserved".format(self._id))

    def release(self):
            print("Node {} released".format(self._id))

class Cluster:
    def __init__(self, id):
        self._id = id
        self._nodes = [Node(1), Node(2), Node(3), Node(4)]

    @contextmanager
    def reserved(self):
        with ExitStack() as cm:
            cm.enter_context(node.reserved() for node in self._nodes)
            print("Cluster {} reserved".format(self._id))
            try:
                yield
            except:
                print("Exception while handling cluster")
            finally:
                print("Cluster released")
    @contextmanager
    def reserved2(self):
        with ExitStack() as cm:
            for node in self._nodes:
                reserve = node.reserve()
                cm.callback(node.release(), reserve)

            print("Cluster {} reserved".format(self._id))
            try:
                yield
            except:
                print("Exception while handling cluster")
            finally:
                print("Cluster released")

node = Node(10)
with node.reserved():
    print('Node {} handled'.format(node._id))


cluster = Cluster(10)
with cluster.reserved2():
    print('Cluster {} handled'.format(cluster._id))

保留第一个函数()returns

AttributeError: type object 'generator' has no attribute '__exit__'

而第二个在保留所有节点后并没有真正屈服。想知道处理这个问题的正确方法是什么...

cm.enter_context(node.reserved() for node in self._nodes)

该代码不正确。我应该正确地使用列表理解将上下文管理器对象正确地传递给 enter_context