python - 是否可以在 python 中使用 `with` 打开任意数量的项目?

标签 python python-3.x

<分区>

我遇到这样一种情况,我有几个项目想使用 with block 打开。就我而言,这些是外部硬件设备,在关闭时需要进行一些清理——但这对当前的问题来说并不重要。

假设一个类是这样的:

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),做类似的事情

with Controller("thing1") as c1:
    with Controller("thing2") as c2:
        c1.do_work()
        c2.do_work()

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

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

但是,上面的内容并没有完全满足我的需要——即一次性为范围内的所有事物设置Controllers

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

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)

但我不喜欢实际函数调用的递归或抽象。我对以更“pythonic”的方式执行此操作的想法很感兴趣。

最佳答案

是的,有一种更 pythonic 的方法可以做到这一点,使用标准库 contextlib,它有一个 ExitStack 类,它可以完全满足您的需求:

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

这应该做你想做的。

关于python - 是否可以在 python 中使用 `with` 打开任意数量的项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48288351/

相关文章:

python - 通过http python发送图像

python - 错误提示而不是提示重新输入输入

python - 导入错误 : No Module named 'driver' in pyttsx

python - scipy.sparse.hstack(([1], [2])) -> "ValueError: blocks must be 2-D"。为什么?

python - 如何调试MySQL错误消息: Caught an exception while rendering

python - 如何在python中将列表从元素n切片到末尾?

python - 'utf- 8' codec can' t 解码字节读取 Python3.4 中的文件,但不是 Python2.7

python - 使 HelloWorld python 脚本可执行

python-3.x - 无法从轮格式安装 NumPy

python - 如何在 Hangman 游戏中通过一次猜测激活多个字母?