关于内存地址的变量赋值和修改

Variable assignment and modification with regards to memory addresses

假设我将两个变量分配给整数:

a = 1
b = 2

现在,我将 a 分配给 b:

a = b

果然是a == 2,因为a已经设置为b的内存地址了。

但实际上并没有。如果我这样做

b += 1

a 仍然等于 2。为什么 a 不指向 b

示例中的行为如下

In [1]: a = 1                                                                                                                                                                     

In [2]: b = 2                                                                                                                                                                     

In [3]: a = b                                                                                                                                                                     

In [4]: b+=1                                                                                                                                                                      

In [5]: b                                                                                                                                                                         
Out[5]: 3

In [6]: a                                                                                                                                                                         
Out[6]: 2

在例子中,当你做a=b时,a和b都指向同一个引用,但是当你b += 1时,将1加到b的操作,创建一个新的整数b 和 b 的值 3 指向该值,但 a 仍指向旧值 2

请注意,尝试使用可变类型(如列表)来执行此操作就像您排除的情况一样发生在整数上

In [1]: a = [1]                                                                                                                                                                   

In [2]: b = [2]                                                                                                                                                                   

In [3]: a = b                                                                                                                                                                     

In [4]: b.append(2)                                                                                                                                                               

In [5]: a                                                                                                                                                                         
Out[5]: [2, 2]

In [6]: b                                                                                                                                                                         
Out[6]: [2, 2]

In [7]: b += [3, 4];                                                                                                                                                                        

In [8]: b
Out[8]: [2, 2, 3, 4]

In [9]: a
Out[9]: [2, 2, 3, 4]

现在这里发生了什么?我们更改了 ba 也更改了,这是因为 append 或列表更新发生 in-place 并且因为 a 指向 b 最终都得到更新!

+= 运算符发生的情况由 class 的 __iadd__ 方法定义。对于 int-s 所有 __iXXX__ 方法 return 一个新的 int 实例。对于 list-s __iadd__(self, other)self.extend(other); return self,所以变量一直指向同一个对象。

因此,即使是整数也可以作为列表使用,例如 here @imposeren

python中的变量是引用。很少有引用指向不可变对象(例如字符串、整数等),而列表和集合是可变的。

Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 22:20:52) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
# Consider two variables x & y  with integers 23 and 46. They have immutable references
# Meaning, if y=x, it doesn't mean y will change whenever x is updated.
>>> x=23
>>> print (x)
23
>>> y=46
>>> print (x)
23
>>> print (y)
46
>>> y=x
>>> print (x)
23
>>> print (y)
23
# Let's change the value of x after the assignment
>>> x=99
>>> print (x)
99
# Since it is immutable, the value wont change.
>>> print (y)
23
#Let's consider the mutable reference scenario. a & b are two lists which have mutable references
# Meaning, if b=a, it means b will change whenever a is changed
>>> a = list([11,22,33,87])
>>> print (a)
[11, 22, 33, 87]
>>> b = list([87,53,98,2])
>>> print (b)
[87, 53, 98, 2]
>>> a=b
>>> print (a)
[87, 53, 98, 2]
>>> print (b)
[87, 53, 98, 2]
# Popping the list would alter b
>>> b.pop()
2
>>> print (b)
[87, 53, 98]
# Notice the change in value of a
>>> print (a)
[87, 53, 98]
>>>

在其他编程语言中,您所说的称为“指针”。
他们有这个名字是因为他们“指向”事物。
a 指向 bb 指向 2,依此类推。

我画了一些图来描述你认为会发生什么,以及实际发生了什么。

您预期会发生什么:

实际发生了什么: