python原子数据类型

时间:2016-08-24 14:01:40

标签: python types variable-assignment atomic

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

我的问题是: 为什么然后,当我做代码时,我得到'真'?

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

在我看来,我不复制价值,我只是复制参考,无论它是什么类型。

3 个答案:

答案 0 :(得分:5)

Python中的赋值(绑定)永远不会复制数据。它始终复制对绑定值的引用。

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

a = b

已执行,

a is b

总是如此 - 这就是赋值在Python中的作用。对于容器也是如此,因此x[i].some_attribute = y会使x[i].some_attribute is y成为真。

Python有原子类型和引用类型的断言似乎对我没有帮助,如果不是简单的不真实。我会说它有原子类型和容器类型。容器是列表,元组,dicts和具有私有属性的实例(首先是近似值)。

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

编辑:最近阅读the English versionthe quoted page(我恐怕我不懂俄语)我看到“Python使用动态类型,以及引用计数和循环检测垃圾的组合收集器用于内存管理。“俄语页面可能误译了这一点,给人一种错误的语言印象,或者被OP误解了。但Python没有“引用类型”,除了weakrefs和类似结构的最特殊意义。

答案 1 :(得分:0)

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

对于像列表这样的可变对象,你可以使用字典

import copy
a = copy.deepcopy(b)

答案 2 :(得分:-1)

实际上像@spectras说只有引用,但有不可变的对象,如float s,int s,tuple s。对于不可变对象(除了内存消耗),如果你传递引用或创建副本也没关系。

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

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

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

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