【问题标题】:identifying objects, why does the returned value from id(...) change?识别对象,为什么 id(...) 的返回值会改变?
【发布时间】:2010-08-04 04:51:20
【问题描述】:

id(对象)

这是一个整数(或长整数),保证在其生命周期内对于该对象是唯一且恒定的。

你能解释一下这个输出吗?为什么j的id变了?

>>> i=10  
>>> id(i)  
6337824  
>>> j=10  
>>> id(j)  
6337824  
>>> j=j+1  
>>> id(j)  
6337800  
>>> id(i)  
6337824  

【问题讨论】:

  • 是不是 i 和 j 最初是对同一个对象的对象引用。但是当 j 发生变化时,它们开始引用不同的对象?
  • 关于它们最初相同的原因,请参阅 [ Python “is” 运算符对整数的行为异常](stackoverflow.com/questions/306313/…)。基本上,int 是不可变的对象,但小的都被保留作为优化。

标签: python


【解决方案1】:

因为整数是不可变的,所以每个整数值都是具有唯一 ID 的不同对象。整数 1011 具有不同的 id。执行j=j+1 不会更改现有整数对象的值,而是将j 更改为指向11 的对象。

看看当我们独立创建一个新变量k并将其赋值为11时会发生什么:

>>> j=10
>>> id(j)
8402204
>>> j=j+1
>>> id(j)
8402192
>>> k=11
>>> id(k)
8402192

请注意,并非每个整数都有一个且只有一个对应的对象。这只发生在 Python 决定缓存的小整数上。大整数不会发生这种情况:

>>> x = 123456789
>>> id(x)
8404568
>>> y = 123456789
>>> id(y)
8404604

https://docs.python.org/3/c-api/long.html#c.PyLong_FromLong:

当前的实现为 -5 到 256 之间的所有整数保留一个整数对象数组,当您在该范围内创建一个 int 时,实际上您只是获取对现有对象的引用。

【讨论】:

    【解决方案2】:

    这就是2**8 is 2**8 == True2**9 is 2**9 == False 的原因。

    -5 到 256 之间的值是预先分配的。

    【讨论】:

      【解决方案3】:

      不同变量的相同id是Python创建变量的产物。

      id 是内存中对象位置的哈希值。 Python 变量是对象的引用,而不是新对象。如果多个变量引用同一个对象,则它们具有相同的 `id。

      【讨论】:

        【解决方案4】:

        在CPython中,id一般来源于Py_Object的指针值,即它在内存中的位置。

        【讨论】:

          【解决方案5】:

          Python 缓存不可变对象(读取整数和元组..)——这就是它们不可变的原因 如果您在许多中引用相同的不可变对象,则可以节省内存 地方。所以small 整数、空元组等实际上是 缓存在 Python 运行时中,因此您不断取回相同的对象 因此相同的 id。

          试试这个列表,你不会得到相同的 id。

          【讨论】:

          • Python 不会缓存所有不可变对象。事实上,它甚至不缓存所有整数。见this answer
          【解决方案6】:

          这些都是原始类型,所以我猜每个值都有自己的 ID。尝试创建一个真实的对象,我想你会看到你所期望的功能。

          如果您需要一个原始类型的 id,您可以创建一个只包含该类型的一个成员的对象。

          【讨论】:

          • python中的每件事都是一个对象,python中没有java中的原始类型这种东西
          【解决方案7】:

          j 的 id 发生变化,因为j 命名的对象发生了变化。首先将j 初始化为10,因此当您调用id(j) 时,您将获得10 的id。然后你将j 设置为11,所以之后当你调用id(j) 时,你会得到11 的id。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-01-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多