首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么id({}) == id({})和id([]) == id([])在CPython中?

为什么id({}) == id({})和id([]) == id([])在CPython中?
EN

Stack Overflow用户
提问于 2010-10-06 22:00:39
回答 3查看 2.5K关注 0票数 29

为什么CPython (不知道其他Python实现)有以下行为?

代码语言:javascript
复制
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([]))

我有一些想法,为什么可能,但找不到一个具体的原因。

编辑

为了进一步证明格伦和托马斯的观点:

代码语言:javascript
复制
[1] id([])
4330909912
[2] x = []
[3] id(x)
4330909912
[4] id([])
4334243440
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-10-06 22:08:54

CPython是垃圾收集对象,一旦超出范围,第二个[]就会在收集第一个[]之后创建。所以,大多数情况下,它会在相同的内存位置结束。

这非常清楚地显示了正在发生的事情(在Python的其他实现中,输出可能有所不同):

代码语言:javascript
复制
class A:
    def __init__(self): print("a")
    def __del__(self): print("b")

# a a b b False
print(A() is A())
# a b a b True
print(id(A()) == id(A()))
票数 42
EN

Stack Overflow用户

发布于 2010-10-06 22:08:56

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

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

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

票数 45
EN

Stack Overflow用户

发布于 2010-10-06 22:08:34

列表和dicts上的==运算符不对对象if进行比较,以确定它们是否是同一个对象--为此使用obj1 is obj2

相反,==操作符将dict列表的成员进行比较,以查看它们是否相同。

票数 -6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3877230

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档