夸克的轮廓:Python对象身份

什么是Python中的对象身份?

Python中的每个对象都有一个唯一的身份。身份告诉Python对象在内存中的位置。只要对象存在,这个身份就是固定的,不会改变。

您可以使用 id() 函数检查对象的身份。您还可以使用 is 运算符比较两个对象的身份。如果两个名称指向同一个对象,它们的身份就是相同的。

Python允许您使用 isid() 比较对象身份。

a = [1, 2, 3]
b = a

print(a is b)       # True
print(id(a), id(b)) # Same number
这两个名称指向内存中的同一个对象。

身份与值有什么不同?

对象的值是它所包含的内容。身份是它所处的位置。两个对象可以具有相同的值,但身份不同。这种情况在可变对象(如列表)中经常发生。

身份在你想知道两个名称是否指向完全相同的对象时非常有用。它并不能告诉你它们的内容是否相等。这就是 == 运算符的作用。


对象身份来自哪里?

对象身份的概念源于早期计算机,在那里内存中的每个项目都有一个地址。Python 保留了这一概念,以帮助管理内存和对象行为。

人们建立了基于内存的系统。

1945年 — 具有地址身份的内存模型,冯·诺依曼架构为每个值提供了一个固定的位置。

1972年 — C语言中的指针,使对象身份变得可见并有助于跟踪内存。

1983年 — 引用计数,在CPython中使用,用于跟踪有多少名称指向一个对象。

人们将身份作为Python的一部分。

1991 — Python 0.9.0,每个对象都有一个唯一的身份,可以通过 is 进行比较。

2000 — id() 函数稳定,Python 2.0 使得 id() 始终返回一个反映对象身份的数字。

2025 — 身份规则不变,Python 仍然在底层使用内存地址身份。


对象身份如何帮助你了解事物的本质?

Python 使用身份来帮助追踪名称所指代的内容。当测试共享状态、缓存或理解变更时,身份是非常有用的。这些示例展示了对象身份如何帮助解决常见任务。


问题 1:测试两个名称是否指向同一个对象

问题:你把一本书递给你的朋友。后来,你的朋友把书还给你。你想知道这是否是同一本书。

解决方案:使用 is 运算符来检查身份。使用 == 来检查值。

Python 让你可以测试两个名称是否指向同一个对象。


book1 = ["title", "author"]
book2 = book1
print(book1 is book2)  # True

这两个名称都指向内存中的同一个对象。


问题 2:相同的值,不同的对象

问题:你有两个看起来相同的塑料杯,但它们并不是同一个副本。

解决方案:两个对象可能看起来相同,但位于不同的位置。使用 is 来测试身份。

Python 允许你区分相同值和相同对象的情况。

cup1 = [1, 2]
cup2 = [1, 2]
print(cup1 == cup2)  # True
print(cup1 is cup2)  # False

这两个列表对象是不同的,尽管它们看起来相同。


问题 3:跟踪共享变更

问题:你发放了两份表单的副本。你更改了一份,另一份也随之更改。你意识到它们是同一份副本。

解决方案:当两个名称共享身份时,一个的变化会影响另一个。

Python 允许你通过身份追踪共享状态。


form1 = {"name": "Ada"}
form2 = form1
form2["name"] = "Alan"
print(form1["name"])  # "Alan"

这两个名称指向同一个字典,因此其中一个的变化在两个名称中都会体现。


问题 4:不可变类型中的身份重用

问题:你在两行中分别赋值 a = 1b = 1。你想知道它们是否是同一个对象。

解决方案:对于像整数这样的较小不可变类型,Python 可能会重用相同的对象。

Python 可能会重用具有相同值的不可变对象。

a = 1
b = 1
print(a is b)  # 通常为 True

Python 可能会给两个名称相同的身份,但这并不保证对所有值都适用。


问题 5:避免意外共享状态

问题:你想要复制一个列表,但两个名称指向同一个列表。当你改变一个时,另一个也会改变。

解决方案:使用 copy() 或切片来创建一个具有新身份的新对象。

Python 通过复制让你避免共享身份。

a = [1, 2, 3]

b = a.copy()
a[0] = 99
print(b[0])  # 仍然是 1
现在 ab 指向不同的对象,但它们的初始值相同。 

你觉得这有帮助吗?请通过点击下面的点赞按钮告诉我。我也很想听听你在评论中的想法!如果你想看到更多类似的内容,不要忘记订阅我的频道。感谢你的阅读!

更多