带括号的上下文管理器
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
这也使差异更具可读性。
【讨论】:
以上是关于带括号的上下文管理器的主要内容,如果未能解决你的问题,请参考以下文章