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 所说的那样,只有引用但是有不可变的对象,如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
为假(==
按预期正常工作)
不可变对象是原子的,更改它们是线程安全的,因为您实际上并没有更改对象本身,而只是在变量中放置一个新引用(这是线程安全的)。
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 和类似的结构。
here 写道 Python 具有原子和引用对象类型。原子对象是:int、long、complex。 分配原子对象时,它的值被复制,当分配引用对象时,它的引用被复制。
我的问题是: 那为什么,当我执行下面的代码时,我得到 'True'?
a = 1234
b = a
print id(a) == id(b)
在我看来,我不复制价值,我只是复制引用,不管它是什么类型。
int 类型是不可变的。 你看到的是数字 1234 的参考,它永远不会改变。
对于列表、字典等可变对象,您可以使用
import copy
a = copy.deepcopy(b)
实际上就像@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
为假(==
按预期正常工作)
不可变对象是原子的,更改它们是线程安全的,因为您实际上并没有更改对象本身,而只是在变量中放置一个新引用(这是线程安全的)。
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 和类似的结构。