使用id()时[]和list()有区别吗?

Is there a difference between [] and list() when using id()?

有人可以解释一下吗?

为什么id一样,list却不一样?

>>> [] is []
False
>>> id([]) == id([])
True

创建列表有区别吗?

>>> 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() 完成后,就不再引用它了。所以下次你使用 id([]) Python 时,你会发现有机会重新使用内存,你瞧,那些地址确实是一样的。

但是,这是一个实现细节,您不能依赖它,它并不总是能够重用内存地址。

请注意,id() 值仅在对象的生命周期内是唯一的,请参阅 documentation:

This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

(大胆强调我的)。

id(list()) 无法重新使用内存位置可能是由于将当前帧压入堆栈以调用函数,然后在 list() 调用 returns.

[]list()都产生一个new空列表对象;但您需要先创建对这些单独列表的引用(此处 ab):

>>> 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>

这会创建一个额外的引用,因此 __repr__ 方法,以及您为其创建的空列表 仍然被认为是活动的 。内存位置未释放且不可用于您创建的下一个列表。

但是再次执行 [].__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>

您永远不会创建两个以上的列表;上一个(仍由 _ 引用)和当前一个。如果您想查看更多内存位置,请使用变量添加另一个引用。