这里的关键是可变性和不变性。
在python中没有原始和非原始之分,一切都是类型,有些只是内置的。
您需要了解 python 如何将数据存储在变量中。假设您来自 C 背景,您可以认为所有 Python 变量都是指针。
所有 Python 变量都将引用存储到变量值实际所在的位置强>。
内置的id 函数让我们可以查看变量值的实际存储位置。
>>> x = 12345678
>>> id(x)
1886797010128
>>> y = x
>>> id(y)
1886797010128
>>> y += 1
>>> y
12345679
>>> x
12345678
>>> id(y)
1886794729648
变量x 指向位置1886797010128,位置1886797010128 保存10 的值。 int是python中的不可变类型,也就是说1886797010128位置存储的数据是不能改变的。
当我们分配y = x 时,y 现在也指向同一个地址,因为没有必要为同一个值分配更多的内存。
当y 改变时(记住int 是一个不可变类型并且它的值不能改变),一个新的int 被创建在新的位置1886794729648 和y 现在指向这个新的新地址处的 int 对象。
当您尝试更新包含不可变数据的变量的值时,也会发生同样的情况。
>>> id(x)
140707671077744
>>> x = 30
>>> id(x)
140707671078064
更改具有不可变数据的变量的值只会使变量指向具有更新值的新对象。
对于像list 这样的可变类型,情况并非如此。
>>> a = [1, 2, 3]
>>> b = a
>>> id(a), id(b)
(1886794896456, 1886794896456)
>>> b.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>>
a 是一个list 并且是可变的,使用像append 这样的方法来改变它实际上会改变地址1886794896456 的值。由于b 也指向同一个地址,a 的值也会更新。
deepcopy 在不同的内存位置创建一个与其参数值相同的新对象,即传递给它的对象。
我想知道做出这种设计选择的原因
这仅仅是因为 python 被设计为一种面向对象的语言。在 java 对象中可以看到类似的行为。
我个人认为这种行为违反直觉
直觉来自实践。练习一种语言并不能帮助了解其他语言的工作方式,不同的语言有不同的设计模式和约定,我认为应该付出一些努力来了解它们对于我们将要使用的语言是什么。