有人能解释一下这是怎么回事吗?为什么会出现这种情况?
>>> b = "1984"
>>> a = b, c = "AB"
>>> print(a, b, c)
'AB', 'A', 'B'
这种行为真的让我大吃一惊。 找到这个here
最佳答案
赋值是一个语句;它被定义为将最右侧从左到右分配给各个目标。比较干燥language grammar description is :
An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.
例如:
a = b = 1
将 1
分配给 a
,然后再次将其分配给 b
,与您的操作大致相同:
__specialtmp = 1
a = __specialtmp
b = __specialtmp
其中__specialtmp
是一个未命名的临时存储位置(在CPython上,它只是加载到程序堆栈的顶部,然后复制到两个引用中,然后弹出每个引用以进行分配)。
这只是添加了可迭代的拆包;以同样的方式扩展您的代码,它看起来像:
__specialtmp = "AB"
a = __specialtmp # Assigns original value to a
b, c = __specialtmp # Unpacks string as iterable of its characters, assigning "A" to b, and "B" to c
请注意,这并不总是有效;如果被解包的东西是一个迭代器,并且您首先分配给解包的名称,则迭代器将耗尽,并且对于第二次分配将没有任何有用的信息:
b, c = [*a] = iter("AB")
这会将 "A"
解压为 b
,将 "B"
解压为 c
,但是当它得到时到 a
,简单来说,[*a] = iter("AB")
将变为 ["A", "B"]
(星形语法将“剩余”值捕获到列表中),在这种情况下,迭代器会耗尽填充 b
和 c
和 a
什么也没有(空的列表
,[]
)。
重点是,虽然这个技巧有效,但我一般不会推荐它。将多个名称初始化为相同的不可变值是可以的,但否则可能会造成困扰。
关于Python 解包陷阱(意外行为),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59276156/