多行上的Python嵌套上下文管理器

多行上的Python嵌套上下文管理器,python,with-statement,contextmanager,Python,With Statement,Contextmanager,在Python 2.6中,我们使用这种方式格式化嵌套上下文管理器: with nested( context1, context2 ) as a, b: pass 在Python2.7及更高版本中,nested被弃用。我在一行中看到了许多多上下文管理器的示例,但我找不到允许它们在多行中使用的语法。你会怎么做 # That's working fine with context1 as a, context2 as b: pass # But how do we

在Python 2.6中,我们使用这种方式格式化嵌套上下文管理器:

with nested(
    context1,
    context2
) as a, b:
    pass
在Python2.7及更高版本中,
nested
被弃用。我在一行中看到了许多多上下文管理器的示例,但我找不到允许它们在多行中使用的语法。你会怎么做

# That's working fine
with context1 as a, context2 as b:
    pass

# But how do we make it multine?
# These are not working
with (
    context1,
    context2
) as a, b:
    pass

with context1 as a,
    context2 as b:
    pass
反斜杠字符 两条或多条物理线可以使用 反斜杠字符(
\

(引用该节)

如果要将上下文管理器放在不同的行上,可以使用反斜杠结束行:

with context1 as a,\
     context2 as b:
    pass
contextlib.ExitStack
是一个

上下文管理器,旨在通过编程轻松地 结合其他上下文管理器和清理功能,尤其是 可选的或由输入数据驱动的

它在Python3.3及更新版本中可用,并允许轻松地输入可变数量的上下文管理器。对于两个上下文管理器,用法如下所示:

from contextlib import ExitStack

with ExitStack() as es:
    a = es.enter_context(context1)
    b = es.enter_context(context2)
筑巢 可以使用语句将上下文表达式拆分为多个嵌套的

对于多个项目,上下文管理器的处理就像 嵌套了多个with语句:

with A() as a, B() as b:
套房相当于

with A() as a:
    with B() as b:
        suite
(来自)


与任何换行符一样,反斜杠提供了解决方案,您的示例相当于:

with context1 as a:
    with context2 as b:
        pass
在两条线上看起来不错


参考资料:

有一种方法可以创造性地使用括号并避免反斜杠:将表达式插入
前面的括号中,作为
。但不是很明显:

with (
  open('/etc/passwd')) as foo, (
  open('/tmp/bar')) as bar:
  pass  # this parses correctly

如果需要,可以很容易地嵌套越来越多的内容。

这是唯一的语法吗?因为它非常难看…:(不敢相信我是这么说的,但在本例中,python语法与lisp相比非常糟糕。在(let)或其他绑定形式中的多个赋值看起来非常自然……但这很尴尬。如果
B()
需要
a
?有没有办法传递它?不知道为什么会被标记为重复。另一篇文章没有回答这个问题。我同意Python应该为if语句提出一种基于括号的语法。这是最漂亮的解决方案。谢谢!在这种情况下,为什么要避免反斜杠呢?OpenPAREN在这里起着基本相同的作用,但它也变得更加神秘。@isarandi:作为行延续的反斜杠在编辑时比其他东西更容易被打断。PEP-8建议使用paren来支持反斜杠延续。顺便说一句,同样的PEP-8建议对多个
with
语句使用
\
。我个人更喜欢用
嵌套
,但为了完整性添加了这个答案。
with (
  open('/etc/passwd')) as foo, (
  open('/tmp/bar')) as bar:
  pass  # this parses correctly