我惊讶地发现,在 Python 3 中,前两个没有任何问题:
>>> [] = ()
>>> () = ()
>>> {} = ()
File "<stdin>", line 1
SyntaxError: can't assign to literal
在 Python 2.7 中,只有第一个不会引发任何问题:
>>> [] = ()
>>> () = ()
File "<stdin>", line 1
SyntaxError: can't assign to ()
>>> {} = ()
File "<stdin>", line 1
SyntaxError: can't assign to literal
这里发生了什么?为什么其中任何一个都不会引发错误?为什么 () = ()
可能被添加为在 Python 3 中有效?
*注意,您可以将右侧替换为任何空的可迭代对象(例如 [] = set()
),我只是为插图选择了一个空元组
最佳答案
根据Issue23275 ,这些基本上是怪癖,不会造成真正的伤害,也没有实用性。注意 [] = ()
不会改变 list
文字:
>>> [] = ()
>>> type([])
<class 'list'>
[] = x
语句基本上断言 x
是可迭代的并且 x
是空的(尽管没有人会推荐使用它们方式),例如
>>> [] = (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
作为 John Y最好将 [] = ()
视为不是赋值,而是与 Python 的可迭代解包语法保持一致的一种方式。
作为 ArrowCase注释,这种语法也扩展到多个赋值:
>>> a = [] = ()
>>> a
()
查看多重赋值的 CPython 字节码说明此操作类似于正常的可迭代解包语法,使用 UNPACK_SEQUENCE
说明:
>>> 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
同样的 Issue23275 指出 () = ()
已作为有效语法添加到 Python 3 以保持一致性。决定删除 [] = ()
会不必要地破坏代码,因为它不会造成伤害并且符合可迭代的解包逻辑。 {} = ()
仍然无效,因为在这种带有大括号的上下文中,解包语法没有意义。
如果有人想知道,像 list() = ()
这样的语法在语法上是无效的,因为你永远不能分配给函数调用。
关于python - [] = ()、() = () 和 {} = () 'assignments',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48446168/