[] = (), () = (), and {} = () '赋值' [英] [] = (), () = (), and {} = () 'assignments'
问题描述
我惊讶地发现以下内容,在 Python 3 中,前两个没有引发任何问题:
<预><代码>>>>[] = ()>>>() = ()>>>{} = ()文件<stdin>",第 1 行语法错误:无法分配给文字在 Python 2.7 中,只有第一个不会引发任何问题:
<预><代码>>>>[] = ()>>>() = ()文件<stdin>",第 1 行语法错误:不能分配给 ()>>>{} = ()文件<stdin>",第 1 行语法错误:无法分配给文字这里发生了什么?为什么其中任何一个都不会引发错误?为什么 () = ()
可能被添加为在 Python 3 中有效?
*注意,您可以用任何空的可迭代对象替换右侧(例如 [] = set()
),我只是为插图选择了一个空元组
根据 Issue23275,这些基本上是怪癖,不会造成真正的伤害,但也没有效用.注意 [] = ()
不会改变 list
文字:
[] = x
语句基本上断言 x
是可迭代的并且 x
是空的(尽管没有人会推荐使用它们方式),例如
作为 John Y 的评论,最好考虑 [] = ()
不是赋值,而是一种与 Python 的可迭代解包语法保持一致的方式.
正如 ArrowCase 注释,此语法也扩展到多个赋值:
<预><代码>>>>a = [] = ()>>>一种()查看多重赋值的 CPython 字节码说明此操作类似于普通的可迭代解包语法,使用 UNPACK_SEQUENCE
指令:
同样的 Issue23275 指出 () = ()
已作为有效语法添加到 Python 3 中以保持一致性.决定删除 [] = ()
会不必要地破坏代码,因为它不会造成伤害并且符合可迭代的解包逻辑.{} = ()
仍然无效,因为解包语法在带大括号的上下文中没有意义.
如果有人想知道,像 list() = ()
这样的语法在语法上是无效的,因为你永远不能分配给函数调用.
I was surprised to find the following, in Python 3, the first two raise nothing:
>>> [] = ()
>>> () = ()
>>> {} = ()
File "<stdin>", line 1
SyntaxError: can't assign to literal
In Python 2.7, only the first one raises nothing:
>>> [] = ()
>>> () = ()
File "<stdin>", line 1
SyntaxError: can't assign to ()
>>> {} = ()
File "<stdin>", line 1
SyntaxError: can't assign to literal
What is going on here? Why are any of then not raising errors? And why was the () = ()
presumably added to be valid in Python 3?
*Note, you can replace the right hand side with any empty iterable (e.g. [] = set()
), I just choose an empty tuple for the illustration
According to Issue23275, these are basically quirks causing no real harm but also no utility. Note that [] = ()
does not alter the list
literal:
>>> [] = ()
>>> type([])
<class 'list'>
[] = x
statements basically assert that x
is iterable and that x
is empty (although no-one would recommend using them this way), e.g.
>>> [] = (1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> [] = (1,)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
As John Y comments it is best to think of [] = ()
as not an assignment but a way of being consistent with Python's iterable unpacking syntax.
As ArrowCase comments, this syntax also extends to multiple assignments:
>>> a = [] = ()
>>> a
()
Looking at the CPython bytecode of the multiple assignment illustrates that this operations are similar to the normal iterable unpacking syntax, using the UNPACK_SEQUENCE
instruction:
>>> dis.dis('a = [] = ()')
1 0 BUILD_TUPLE 0
2 DUP_TOP
4 STORE_NAME 0 (a)
6 UNPACK_SEQUENCE 0
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
>>> dis.dis('[a, b] = (1, 2)')
1 0 LOAD_CONST 3 ((1, 2))
2 UNPACK_SEQUENCE 2
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 LOAD_CONST 2 (None)
10 RETURN_VALUE
The same Issue23275 states that () = ()
was added as valid syntax to Python 3 for concordance. It was decided that removing [] = ()
would break code needlessly, since it causes no harm and fits with iterable unpacking logic. {} = ()
is still invalid because the unpacking syntax does not make sense in this context with braces.
In case anyone is wondering, syntax like list() = ()
is simply syntactically invalid, because you can never assign to function call.
这篇关于[] = (), () = (), and {} = () '赋值'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!