【发布时间】:2018-01-16 19:17:00
【问题描述】:
我有几个项目想使用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)
我会(给定固定数量的Controllers),做类似的事情
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()
但是,以上内容并不能完全满足我的需要——即一次将所有things 都包含在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”的方式执行此操作的想法很感兴趣。
【问题讨论】:
-
让它成为一个完整的答案已经@MegaIng
-
This 可能是更好的欺骗目标。谨慎选择,关闭选民。
标签: python python-3.x