带括号的上下文管理器

Posted

技术标签:

【中文标题】带括号的上下文管理器【英文标题】:Parenthesized context managers 【发布时间】:2021-08-20 20:09:51 【问题描述】:

我正在尝试了解 Python 3.10 中新的 功能的新功能(新功能中的***项目 here)。

我的测试示例是尝试编写:

with (open('file1.txt', 'r') as fin, open('file2.txt', 'w') as fout):
    fout.write(fin.read())

一个超级简单的测试,它在 Python 3.10 中完美运行。

我的问题是它在 Python 3.9.4 中也能完美运行?

在 Python 3.8.5 中对此进行测试,看起来它不起作用,提高了预期的 SyntaxError

我是否误解了这个更新,因为这个新语法似乎是在 3.9 中引入的?

【问题讨论】:

github.com/python/cpython/commit/… 显示哪些版本支持此功能,一直到v3.9.0b1 我相信允许这样做的 PEG 解析器已添加到 Python 3.9 alpha 6,作为 CPython 的实现细节,而不是 Python 本身的保证特性。请参阅migration plan for PEP-617。 (严格来说,它不是有效的 Python 3.9,尽管 CPython 接受它。例如,PyPy 可以声称支持 Python 3.9 而不接受。) (是的,我知道 PyPy 目前只支持 Python 3.7。我真的不知道在支持的语言版本方面更接近匹配 CPython 的任何替代实现。)跨度> 它的新功能是,以前你不能在括号内放一个或多个括号,这样可以很容易地将多个一个分布在几行上——所以人们经常做的是用一个结束行反斜杠换行符(通常被认为是丑陋的 - 请参阅PEP 8 - Style Guide for Python Code)。 @chepner 好的,所以启用更改的 PEG 解析器意味着允许新语法,但直到 3.10 才正式支持?太棒了,解释了很多,谢谢! 【参考方案1】:

我不知道这是在里面,但我很高兴看到它。专业上我用过 3.6(它没有这个),并且有多个长行上下文管理器和black,真的很难格式化:

如果你有这个:

with some_really_long_context_manager(), and_something_else_makes_the_line_too_long():
    pass

你必须写这个很丑:

with some_really_long_context_manager(), \
    and_something_else_makes_the_line_too_long():
    pass

如果你的论点太长:

with some_context(and_long_arguments), and_another(now_the_line_is_too_long):
    pass

你可以这样做:

with some_context(and_long_arguments), and_another(
    now_the_line_is_too_long
):
    pass

但是,如果一个上下文管理器不接受参数,那就行不通了,而且看起来有点奇怪:

with some_context(and_long_arguments), one_without_arguments(
    ), and_another(now_the_line_is_too_long):
    pass

为此,您必须重新排列:

with some_context(and_long_arguments), and_another(
    now_the_line_is_too_long
), one_without_arguments():
    pass

使用新语法,可以将其格式化为:

with (
    some_context(and_long_arguments),
    one_without_arguments(), 
    and_another(now_the_line_is_too_long), 
):
    pass

这也使差异更具可读性。

【讨论】:

以上是关于带括号的上下文管理器的主要内容,如果未能解决你的问题,请参考以下文章

python3.10.2环境配置

Python 3.10 有哪些新特性 ?

Python 3.10 有哪些最新特性 ?

Python上下文管理器

python上下文管理器

python上下文管理器