python - 为什么 CPython 中的 id({}) == id({}) 和 id([]) == id([])?

标签 python identity cpython python-internals

为什么 CPython(对其他 Python 实现一无所知)有以下行为?

tuple1 = ()
tuple2 = ()                                                                                                   
dict1 = {}
dict2 = {}
list1 = []
list2 = []
# makes sense, tuples are immutable
assert(id(tuple1) == id(tuple2))
# also makes sense dicts are mutable
assert(id(dict1) != id(dict2))
# lists are mutable too
assert(id(list1) != id(list2))
assert(id(()) == id(()))
# why no assertion error on this?
assert(id({}) == id({}))
# or this?
assert(id([]) == id([]))

我有一些想法可能,但找不到具体原因。

编辑

为了进一步证明 Glenn 和 Thomas 的观点:

[1] id([])
4330909912
[2] x = []
[3] id(x)
4330909912
[4] id([])
4334243440

最佳答案

当您调用 id({}) 时,Python 会创建一个字典并将其传递给 id 函数。 id 函数获取它的 id(它的内存位置),并丢弃字典。字典被销毁了。当您快速连续执行两次时(同时没有创建任何其他字典),Python 第二次创建的字典恰好与第一次使用相同的内存块。 (CPython 的内存分配器使这比听起来更有可能。)因为(在 CPython 中)id 使用内存位置作为对象 id,所以两个对象的 id 是相同的。如果您将字典分配给一个变量然后获取它的 id(),这显然不会发生,因为字典同时是事件的,所以它们的id 必须不同。

可变性不会直接发挥作用,但缓存元组和字符串的代码对象会发挥作用。在相同的代码对象(函数或类主体或模块主体)中,将重复使用相同的文字(整数、字符串和某些元组)。可变对象永远不能重复使用,它们总是在运行时创建。

简而言之,对象的 ID 仅在对象的生命周期内是唯一的。在对象被销毁之后或创建之前,其他对象可以具有相同的 id。

关于python - 为什么 CPython 中的 id({}) == id({}) 和 id([]) == id([])?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54274418/

相关文章:

python - `object in list` 的行为与 `object in dict` 不同?

python - CPython 还是 IronPython?

python - 附加项目时列表的长度不相同

c# - Entity Framework - SaveChanges() 未获取生成的身份 key

python - 以下哪项是在 Python 中检查列表是否为空的最快方法?

mysql - 如何将此 MS SQL 脚本重写为 MySQL 脚本?

sql-server - 跨多个表维护标识值

python - 将默认时间添加到字典

python - Python + Qt 组合能否产生实时频谱分析工具?

python - 在 Python 中加密私钥