编写here,Python同时具有原子和引用对象类型。原子对象是:int,long,complex。 分配原子对象时,会复制它的值,当分配引用对象时,它的引用会被复制。
我的问题是: 为什么然后,当我做代码时,我得到'真'?
a = 1234
b = a
print id(a) == id(b)
在我看来,我不复制价值,我只是复制参考,无论它是什么类型。
答案 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 version的the 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
为假(==
正常按预期工作)
不可变对象是原子的,因为更改它们是线程安全的,因为你实际上并没有更改对象本身,只是在变量中添加了一个新引用(这是线程安全的)。