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

时间:2018-01-16 19:17:01

标签: python python-3.x

我有一种情况,我有几个项目,我想使用=TRIM(CONCATENATE(IF(ISNUMBER(SEARCH("yes",A2)),A2&", "," "),IF(ISNUMBER(SEARCH("yes",B2)),B2&", "," "),IF(ISNUMBER(SEARCH("yes",C2)),C2&", "),IF(ISNUMBER(SEARCH("yes",D2)),D2&", "," "),IF(ISNUMBER(SEARCH("yes",E2)),E2&", "," "),IF(ISNUMBER(SEARCH("yes",F2)),F2&", "," "),IF(ISNUMBER(SEARCH("yes",G2)),G2&", "," "),IF(ISNUMBER(SEARCH("yes",H2)),H2&", "," "))) 块打开。在我的情况下,这些是外部硬件设备,在关闭时需要进行一些清理 - 但这对于手头的要点并不重要。

假设课程类似:

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) s),做类似

的事情
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

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

thing

但我不喜欢实际函数调用的递归或抽象。我对在更多" pythonic"中做到这一点的想法很感兴趣。方式。

1 个答案:

答案 0 :(得分:8)

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

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

这应该做你想要的。