我很惊讶地发现以下内容,在Python 3中,前两个没有提出任何内容:
TextInputLayoutTheme
在Python 2.7中,只有第一个没有提出任何内容:
>>> [] = ()
>>> () = ()
>>> {} = ()
File "<stdin>", line 1
SyntaxError: can't assign to literal
这里发生了什么?那么为什么没有提出任何错误呢?为什么>>> [] = ()
>>> () = ()
File "<stdin>", line 1
SyntaxError: can't assign to ()
>>> {} = ()
File "<stdin>", line 1
SyntaxError: can't assign to literal
可能被添加到Python 3中有效?
*注意,你可以用任何空的可迭代替换右边(例如() = ()
),我只选择一个空元组作为插图
答案 0 :(得分:28)
根据Issue23275,这些基本上是怪癖,没有造成真正的伤害,也没有效用。请注意,[] = set()
不会改变[] = ()
字面值:
list
>>> [] = ()
>>> type([])
<class 'list'>
语句基本断言[] = x
是可迭代的,而x
是空的(尽管没有人建议以这种方式使用它们),例如。
x
作为John Y注释,最好将>>> [] = (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
视为不是赋值,而是与Python的可迭代解包语法保持一致的方式。
作为ArrowCase注释,此语法还扩展到多个分配:
[] = ()
查看多重赋值的CPython字节码说明此操作类似于普通的可迭代解包语法,使用UNPACK_SEQUENCE
指令:
>>> a = [] = ()
>>> a
()
相同的Issue23275声明>>> 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
被添加为Python 3的有效语法以实现一致性。决定删除() = ()
会不必要地破坏代码,因为它不会造成任何伤害并且符合可迭代的解包逻辑。 [] = ()
仍然无效,因为在带有大括号的上下文中,解包语法没有意义。
如果有人想知道,像{} = ()
这样的语法在语法上是无效的,因为你永远不能分配给函数调用。
答案 1 :(得分:26)
有一种方法可以从迭代中分配变量:
[] = …
() = …
和{{1}}分配似乎是这些的特殊情况。
答案 2 :(得分:9)
赋值语句的左侧是不表达式,它是target list。简短摘要:
这解释了为什么[]
和()
是分配的有效左侧:它们是有效的目标列表。但是,{}
不是,因为它不是有效的目标列表。
当然,{}
可能是目标的一部分,例如作为订阅的主要部分:{}[()] = 0
是有效的python(当然,但完全没用)。
答案 3 :(得分:7)
这是将两元素迭代解包为两个赋值目标的语法:
[x, y] = whatever
这可以概括最多三个或更多目标,但它也可以概括为:
[x] = whatever
将一个元素的iterable解包到一个赋值目标中,并且
[] = whatever
将零元素迭代解包为零分配目标(如果whatever
是零元素可迭代,则不执行任何操作,如果不是,则抛出异常)。
() = whatever
也解包零元素可迭代,但{} = whatever
没有;没有涉及大括号的解压缩赋值语法。