使用id()时,和list()之间有区别吗?
有人可以解释以下吗?
为什么id相同,但是列表不同?
>>> [] is [] False >>> id([]) == id([]) True
列表创build有区别吗?
>>> id(list()) == id(list()) False >>> id([]) == id([]) True
为什么发生这种情况? 我得到两个不同的名单。 为什么不只一个,或三个或更多?
>>> [].__repr__ <method-wrapper '__repr__' of list object at 0x7fd2be868128> >>> [].__repr__ <method-wrapper '__repr__' of list object at 0x7fd2be868170> >>> [].__repr__ <method-wrapper '__repr__' of list object at 0x7fd2be868128> >>> [].__repr__ <method-wrapper '__repr__' of list object at 0x7fd2be868170>
你用id()
错了。 id([])
将立即丢弃一个对象的内存标识。 毕竟,一旦id()
完成,什么都没有引用它。 所以下次你使用id([])
Python看到了重新使用内存的机会,而且这些地址确实是一样的。
但是,这是一个你不能依赖的实现细节,并不总是能够重用内存地址。
请注意, id()
值仅在对象的生命周期中是唯一的 ,请参阅文档 :
这是一个整数,在整个生命周期中保证这个对象是独一无二的。 两个具有非重叠生命周期的对象可能具有相同的
id()
值。
(大胆强调我的)。
该id(list())
不能重新使用内存位置可能是由于堆栈中的当前帧调用函数引起的额外的堆变化,然后在list()
调用返回时再次popup。
[]
和list()
产生一个新的空列表对象; 但是您需要先创build对这些单独列表(这里a
和b
)的引用:
>>> a, b = [], [] >>> a is b False >>> id(a) == id(b) False >>> a, b = list(), list() >>> a is b False >>> id(a) == id(b) False
当您使用[].__repr__
发生同样的情况。 Python交互式解释器有一个特殊的全局名称_
,你可以用它来引用最后产生的结果:
>>> [].__repr__ <method-wrapper '__repr__' of list object at 0x10e011608> >>> _ <method-wrapper '__repr__' of list object at 0x10e011608>
这会创build一个额外的引用,所以__repr__
方法和扩展名为它创build的空列表仍被视为活动的 。 内存位置未被释放,不能用于您创build的下一个列表。
但是再次执行[].__repr__
,Python现在将_
绑定到新的方法对象。 突然之前的__repr__
方法不再被任何东西引用,并且可以被释放,列表对象也是如此。
第三次执行[].__repr__
,第一个内存位置可以重复使用,所以Python可以做到这一点:
>>> [].__repr__ # create a new method <method-wrapper '__repr__' of list object at 0x10e00cb08> >>> _ # now _ points to the new method <method-wrapper '__repr__' of list object at 0x10e00cb08> >>> [].__repr__ # so the old address can be reused <method-wrapper '__repr__' of list object at 0x10e011608>
你永远不会创build两个以上的列表。 前一个(仍然由_
引用)和当前的一个。 如果你想看到更多的内存位置,使用variables来添加另一个引用。