为什么在Python中多重赋值和单一赋值表现不同

4

我在使用Python中的队列时遇到了错误,在我的代码看起来完美无缺的情况下,后来当我改变了赋值方式时,突然间代码就能正常运行了。以下是修改前的代码:

    x=y=Queue()
    x.put("a")
    x.put("b")
    print y.get()

后来我改成这个,它就开始工作了。

    x=Queue()
    y=Queue()
    x.put("a")
    x.put("b")
    print y.get(10)

为什么这两段代码表现不同呢?

因为在 x=y=Queue() 中,xy 是指向同一对象的引用。 - Ashwini Chaudhary
2
另外,请注意 y.get(10) 可能不是您想要的。Queue.get() 的第一个参数是 block,它被解释为一个布尔值。 - Sam Mussmann
2个回答

13

Python中的变量是引用或名称,不像C等语言中的变量。

以下代码:

x=y=Queue()

这段代码的意思是“允许名称y引用通过调用Queue()创建在内存中的对象,并允许名称x引用y指向的对象。”这意味着两个变量都指向同一个对象,你可以使用id(x) == id(y)来验证。
x=Queue()
y=Queue()

意思是“允许名称x引用由Queue()创建的一个对象,并允许名称y引用另一个由Queue()创建的对象”。在这种情况下,id(x) == id(y)False

这经常会困扰你:

a = [1,2,3,4,5]
b = a
b.append(6)
print(a)
# [1,2,3,4,5,6] even though we didn't seem to do anything to a!

为了解决这个问题,请使用import copy; b = a.copy();而不是b = a
然而,这种行为不会发生在像整数这样的不可变对象上:
a = 7
a += 1

这个操作并不会直接将a所引用的对象加一,而是取消a与数字7的关联,并将其与代表a之前值加一的新对象关联(即8)。这与对可变对象(如上例中的列表)执行的操作不同——在列表中添加元素确实会改变变量所引用的对象。

因此我们可以这样做:

a = 7
b = a
a += 1
print(a)
# 8
print(b)
# 7

3

你的第一段代码实际上等同于:

y=Queue()
x=y
x.put("a")
x.put("b")
print y.get()

这与您第二个示例不同,因为Python通过引用处理对象。在x=y之后,变量xy都指向同一个对象。在您的第二个示例中,您有两个独立的队列。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接