python 原子数据类型

python atomic data types

here 写道 Python 具有原子和引用对象类型。原子对象是:int、long、complex。 分配原子对象时,它的值被复制,当分配引用对象时,它的引用被复制。

我的问题是: 那为什么,当我执行下面的代码时,我得到 'True'?

a = 1234
b = a
print id(a) == id(b)

在我看来,我不复制价值,我只是复制引用,不管它是什么类型。

int 类型是不可变的。 你看到的是数字 1234 的参考,它永远不会改变。

对于列表、字典等可变对象,您可以使用

import copy
a = copy.deepcopy(b)

实际上就像@spectras 所说的那样,只有引用但是有不可变的对象,如floats、ints、tuples。对于不可变对象(除了内存消耗),传递引用或创建副本并不重要。

解释器甚至做了一些优化,使用具有相同值的数字可以互换,使得检查数字的身份变得有趣,因为例如

a=1
b=1
c=2/2
d=12345 
e=12345*1

a is b 为真,a is c 也为真,但 d is e 为假(== 按预期正常工作)

不可变对象是原子的,更改它们是线程安全的,因为您实际上并没有更改对象本身,而只是在变量中放置一个新引用(这是线程安全的)。

Python 中的分配(绑定)从不复制数据。它总是复制对被绑定值的引用。

解释器计算右侧的值,左侧通过引用绑定到新值。如果右侧的表达式是现有值(换句话说,如果不需要运算符来计算其值),则左侧将是对同一对象的引用。

之后

a = b

被执行,

a is b

将始终为真 - 这就是 Python 中赋值的工作方式。对于容器也是如此,因此 x[i].some_attribute = y 将使 x[i].some_attribute is y 为真。

Python 具有原子类型和引用类型的断言对我来说似乎没有帮助,如果不是完全不正确的话。我会说它有原子类型和容器类型。容器是诸如列表、元组、字典和具有私有属性(第一次近似)的实例之类的东西。

正如@BallPointPen 在他们的评论中有用地指出的那样,可以更改可变值而无需重新绑定引用。由于无法更改不可变值,因此必须重新绑定引用才能引用不同的值。

编辑:最近阅读 the English version of the quoted page (I'm afraid I don't understand Russian) I see "Python uses dynamic typing, and a combination of reference counting and a cycle-detecting garbage collector for memory management." It's possible the Russian page has mistranslated this to give a false impression of the language, or that it was misunderstood by the OP. But Python doesn't have "reference types" except in the most particular sense for weakrefs 和类似的结构。