python原子数据类型

uwopmtnx  于 2023-04-04  发布在  Python
关注(0)|答案(4)|浏览(117)

here写道,Python有原子和引用对象类型。原子对象是:int,long,complex。当分配原子对象时,复制其值,当分配引用对象时,复制其引用。
我的问题是:那么,为什么当我做下面的代码时,我得到了“True”?

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

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

vohkndzv

vohkndzv1#

Python中的赋值(绑定)从不复制数据。它总是复制对被绑定值的引用。
解释器计算右边的值,左边的值通过引用绑定到新的值。如果右边的表达式是一个现有的值(换句话说,如果不需要运算符来计算它的值),那么左边的值将是对同一个对象的引用。
之后

a = b

被执行时,

a is b

will ALWAYS be true -这就是Python中赋值的工作方式。对于容器也是如此,所以x[i].some_attribute = y将使x[i].some_attribute is y为true。
Python有原子类型和引用类型的Assert对我来说似乎没有帮助,如果不是完全不正确的话。我会说它有原子类型和容器类型。容器是像列表,元组,字典和带有私有属性的示例(第一近似值)。
正如@BallPointPen在他们的评论中指出的那样,可变值可以在不需要重新绑定引用的情况下进行更改。由于不可变值无法更改,因此必须重新绑定引用才能引用不同的值。
编辑:最近阅读the English versionthe quoted page(恐怕我不懂俄语)我看到“Python使用动态类型,以及引用计数和用于内存管理的循环检测垃圾收集器的组合。”可能俄语页面错误翻译了这一点,给予人一种错误的语言印象,但是Python没有“引用类型”,除了在最特殊的意义上的weakrefs和类似的结构。

rt4zxlrg

rt4zxlrg2#

int类型是不可变的。你看到的是数字1234的引用,它永远不会改变。
对于可变对象,如列表、字典,您可以使用

import copy
a = copy.deepcopy(b)
cl25kdpy

cl25kdpy3#

如果标准Python数据类型不能保证数据操作的原子性,您可以查看https://sharedatomic.top上的共享原子企业Python数据类型

wgeznvg7

wgeznvg74#

实际上,就像@spectras说的,只有引用,但有不可变的对象,如float s,int s,tuple s。对于不可变的对象(除了内存消耗),传递引用或创建副本都无关紧要。
解释器甚至做了一些优化,利用具有相同值的数字是可互换的,这使得检查数字的身份变得有趣,因为例如

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

a is b为true,a is c也为true,但d is e为false(==如预期正常工作)
不可变对象是原子的,就像 * 改变 * 它们是线程安全的一样,因为你实际上并没有改变对象本身,只是在变量中放置了一个新的引用(这是线程安全的)。

相关问题