【问题标题】:Python nested context manager on multiple lines [duplicate]多行上的Python嵌套上下文管理器[重复]
【发布时间】:2015-07-22 18:24:02
【问题描述】:

在 Python 2.6 中,我们曾经以这种方式格式化我们的嵌套上下文管理器:

with nested(
    context1,
    context2
) as a, b:
    pass

从 Python 2.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

【问题讨论】:

  • 不知道为什么这被标记为重复。另一个帖子没有回答这个问题。我同意 Python 应该为 if 语句提出一个基于括号的语法。

标签: python with-statement contextmanager


【解决方案1】:

反斜杠字符

两条或多条物理线可以通过以下方式连接成逻辑线 反斜杠字符 (\)

(引用 Explicit line joining 部分)

如果您想将上下文管理器放在不同的行上,可以通过以反斜杠结束行来实现:

with context1 as a,\
     context2 as b:
    pass

contextlib.ExitStack

contextlib.ExitStack 是一个

上下文管理器旨在简化以编程方式 结合其他上下文管理器和清理功能,尤其是那些 是可选的或由输入数据驱动的。

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

from contextlib import ExitStack

with ExitStack() as es:
    a = es.enter_context(context1)
    b = es.enter_context(context2)

嵌套

可以将上下文表达式拆分为多个嵌套 with 语句:

如果有多个项目,上下文管理器的处理方式就像 多个 with 语句被嵌套:

with A() as a, B() as b:

套件相当于

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

(来自The with statement

【讨论】:

  • 这是唯一的语法吗 - 因为它非常难看... :(
  • 不敢相信我这么说,但在这种情况下,python 语法与 lisp 相比很糟糕。 (let) 或其他绑定形式的多个赋值看起来很自然……但这很尴尬。
  • 如果B() 需要a 怎么办?有没有办法传进去?
【解决方案2】:

有一种方法可以创造性地使用括号并避免使用反斜杠:在as 之前为表达式加上括号。不过不是很明显:

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

如果需要,可以轻松嵌套更多。

【讨论】:

  • 这是最漂亮的解决方案。谢谢!
  • 在这种情况下为什么要避免使用反斜杠呢?开放式括号在这里扮演着基本相同的角色,但它也变得更加神秘。
  • @isarandi:作为续行的反斜杠在编辑时比其他一些东西更容易中断。 PEP-8 建议使用括号来支持反斜杠继续。顺便说一句,相同的 PEP-8 建议使用 \ 与多个 with 语句完全一致。我个人更喜欢嵌套with,但为了完整性添加了这个答案。
【解决方案3】:
with context1 as a, \
context2 as b:
pass

与任何换行符一样,反斜杠提供了解决方案

【讨论】:

    【解决方案4】:

    你的例子相当于:

    with context1 as a:
        with context2 as b:
            pass
    

    两行看起来不错。

    参考:https://docs.python.org/2.7/reference/compound_stmts.html#the-with-statement

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      • 2016-08-02
      • 2021-10-03
      • 2019-06-18
      相关资源
      最近更新 更多