【问题标题】:Reusing multiple contexts in Python 'with' statement在 Python 'with' 语句中重用多个上下文
【发布时间】:2018-11-15 22:53:08
【问题描述】:

在 Python3 中,我们可以在 with 语句中使用多个上下文。但是,如果不能在 with 语句中立即构造它们,是否可以输入多个上下文?有可能做这样的事情吗?

def files():
    return open('a.txt', 'w'), open('b.txt', 'w')

with files():
    pass

或者这个:

files = open('a.txt', 'w'), open('b.txt', 'w')
with files:
    pass

【问题讨论】:

  • 这是一个不安全的模式——如果打开第二个文件时出现问题,第一个文件不会被关闭。如果您详细说明为什么要这样做,我们可能会为您提供更好的选择。 (ExitStack 很可能参与其中。)
  • @user2357112 是的......本来建议看看contextlib.ExitStack,因为这是我的直觉,但我仍然不确定用例是什么......
  • 有没有办法让它安全,例如复制with open(...), open()... 的行为。也许将上下文保存到变量中并不好,但是带有函数的模式应该是安全的。

标签: python python-3.x with-statement


【解决方案1】:
from contextlib import contextmanager

@contextmanager
def files():
    with open('a.txt', 'w') as f1, open('b.txt', 'w') as f2:
         yield f1,f2

也许?

with files() as (f1,f2):
     print(f1,f2)

【讨论】:

  • 但是你返回了两个关闭的文件。
  • 还要在with files() as f1,f2 中的f1,f2 周围加上括号,否则优先级不会按您想要的方式工作。
【解决方案2】:

一个使用contextlib.ExitStack的例子:

from contextlib import ExitStack

def files(stack, *args):
    return [stack.enter_context(open(f, "w")) for f in args]

with ExitStack() as stack:
    f1, f2 = files(stack, "a.txt", "b.txt")
    ...

或者没有包装器

with ExitStack() as stack:
    f1, f2 = [stack.enter_context(open(f, "w")) for f in ["a.txt", "b.txt"]]
    ...

但是,当您提前知道要打开多少个文件(并且是少量文件)时,Joran Beasley's answer 中所示的with 语句的多管理器形式会更简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-11
    • 2020-02-29
    • 2016-05-30
    • 2021-05-09
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 2014-04-11
    相关资源
    最近更新 更多