为什么多个赋值和单个赋值在python中表现不同

Sar*_*009 4 python

当我在代码中出现错误时,我正在使用python中的队列,即使代码看起来非常完美,但后者当我改变了赋值样式时,代码开始工作.代码之前看起来像这样.

    x=y=Queue()
    x.put("a")
    x.put("b")
    print y.get()
Run Code Online (Sandbox Code Playgroud)

后来我改为这个,它开始工作了

    x=Queue()
    y=Queue()
    x.put("a")
    x.put("b")
    print y.get(10)
Run Code Online (Sandbox Code Playgroud)

为什么两个代码的工作方式不同

rlm*_*lms 13

Python中的变量是引用或名称,而不是C中的变量等.

这段代码:

x=y=Queue()
Run Code Online (Sandbox Code Playgroud)

表示"允许名称y通过调用引用内存中的对象Queue(),并允许名称x引用y指向的对象." 这意味着两个变量都引用同一个对象 - 您可以验证id(x) == id(y).

这段代码:

x=Queue()
y=Queue()
Run Code Online (Sandbox Code Playgroud)

表示"允许名称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!
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,做import copy; b = a.copy();的不是b = a.

但是,对于整数等不可变对象,不会发生此行为:

a = 7
a += 1
Run Code Online (Sandbox Code Playgroud)

并不去该对象a所引用,并通过加入一个改变它,而不是将其取消引用a从对象7,并且它引用表示的前一值的对象a+ 1(即,8).这与对可变对象执行的操作不同,例如前一个示例中的列表 - 附加到列表更改变量引用的对象.

所以我们可以这样做:

a = 7
b = a
a += 1
print(a)
# 8
print(b)
# 7
Run Code Online (Sandbox Code Playgroud)