为什么 Python 允许解压空的可迭代对象?

wja*_*rea 3 python variable-assignment iterable-unpacking

我正在编写一些代码并犯了一个错字,但没有错误。回溯起来,我发现这些工作有效:

>>> [] = []
>>> () = ()
>>> 
Run Code Online (Sandbox Code Playgroud)

这是可迭代的解包,但没有真正的分配目标。为什么 Python 允许这样做?在某些情况下这很有用吗?

这是在语法中定义的地方。我本以为你至少需要一个identifierattributerefsubscriptionslicing,但显然不需要;target_list在圆括号或中括号内是可选的。

target ::=  identifier
            | "(" [target_list] ")"
            | "[" [target_list] "]"
            | attributeref
            | subscription
            | slicing
            | "*" target
Run Code Online (Sandbox Code Playgroud)

查看文档历史,这在最近的Python 3.42.6中是不可能的,但分配到是在Python 3.52.7以及Python 3.6[]添加的。()

有关的:

注意:由于我询问的是设计选择,因此答案应包括对官方文档或核心开发等权威来源的引用。

wja*_*rea 5

根据相关的Python问题讨论,分配给空列表[]实际上很长一段时间都是可能的,但没有记录。在 3.5 中记录之前,这被认为是“相当无害的怪癖”。()然后添加分配给一个空元组以保持一致性。

在同一线程中,Martin Panter 提供了一个可能的用例

[...] 我特意使用此语法作为一种简洁的方法,以确保生成器耗尽而不再产生任何收益:

>>> def gen():
...     yield "partial computation"
...     print("computation allowed to complete")
... 
>>> g = gen()
>>> next(g)
'partial computation'
>>> [] = g
computation allowed to complete
Run Code Online (Sandbox Code Playgroud)