在python中可以使用'with'打开任意数量的项目吗?

2024-04-19 15:37:50 发布

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

我有一个情况,我有几个项目我想用with块打开。在我的例子中,这些都是外部硬件设备,关闭时需要进行一些清理——但这对手头的问题并不重要。在

假设一个类类似于:

class Controller(object):

    def __init__(self, name):
        self._name = name

    def __enter__(self):
        # Do some work on entry
        print("Entering", self._name)
        return self

    def __exit__(self, type, value, traceback):
        # Clean up (restoring external state, turning off hardware, etc)
        print("Exiting", self._name)
        return False

    def work(self):
        print("Working on", self._name)

我会(给定一个固定数量的Controller)做类似的事情

^{pr2}$

然而,我遇到过这样一种情况:我需要以这种方式管理很多事情。也就是说,我的情况类似于:

things = ["thing1", "thing2", "thing3"] # flexible in size
for thing in things:
    with Controller(thing) as c:
        c.do_work()

但是,上面的方法并不能完全满足我的需要——即一次在作用域中为所有的thing设置{}。在

我创建了一个通过递归工作的玩具示例:

def with_all(controllers, f, opened=None):
    if opened is None:
        opened = []

    if controllers:
        with controllers[0] as t:
            opened.append(t)
            controllers = controllers[1:]

            with_all(controllers, f, opened)
    else:
        f(opened)

def do_work_on_all(controllers):
    for c in controllers:
        c.work()

names = ["thing1", "thing2", "thing3"]
controllers = [Controller(n) for n in names]

with_all(controllers, do_work_on_all)

但我不喜欢实际函数调用的递归或抽象。我对用一种更“Python”的方式来做这件事很感兴趣。在


Tags: nameinselfforondefwith情况
1条回答
网友
1楼 · 发布于 2024-04-19 15:37:50

是的,还有一种更像python的方法来实现这一点,使用标准库contextlib,它有一个ExitStack类,它可以很好地满足您的需要:

with ExitStack() as stack:
    controllers = [stack.enter_context(Controller(n)) for n in names]

这应该是你想要的。在

相关问题 更多 >