gpt4 book ai didi

python - id() 与 `is` 运算符。比较 `id` 是否安全?同样的 `id`是不是代表同一个对象?

转载 作者:太空狗 更新时间:2023-10-29 22:28:34 25 4
gpt4 key购买 nike

我可以在多大程度上依赖对象的 id() 及其在实践中的唯一性?例如:

  • id(a) == id(b) 是指 a is b 还是相反?相反的呢?
  • id 保存到某处供以后使用(例如保存到某个注册表而不是对象本身)有多安全?

(作为对 Canonicals for Python: are objects with the same id() the same object, `is` operator, unbound method objects 的建议规范编写)

最佳答案

根据id() documentation , id 只能保证是唯一的

  1. 特定对象的生命周期,以及
  2. 在特定的解释器实例中

因此,比较 id 是不安全的,除非您还以某种方式确保其 id 被采用的两个对象在比较时仍然存在(并且与同一个 Python 解释器实例相关联,但您需要真正尝试使其变为 false)。

这正是 is 所做的——这使得比较 id 变得多余。如果您出于某种原因不能使用 is 语法,那么总是有 operator.is_ .


现在,在比较时一个对象是否仍然存在并不总是显而易见的(有时是非常-明显的):

  • 访问某些属性(例如 bound methods of an object )每次都创建一个新对象。因此,结果的 id 可能或每个属性访问可能不同。

    例子:

    >>> class C(object): pass
    >>> c=C()
    >>> c.a=1

    >>> c.a is c.a
    True # same object each time

    >>> c.__init__ is c.__init__
    False # a different object each time

    # The above two are not the only possible cases.
    # An attribute may be implemented to sometimes return the same object
    # and sometimes a different one:
    @property
    def page(self):
    if check_for_new_version():
    self._page=get_new_version()
    return self._page
  • 如果一个对象是作为计算表达式的结果创建的,但没有保存在任何地方,它会立即被丢弃,1并且之后创建的任何对象都可以采用增加它的 id

    • 即使在同一行代码中也是如此。例如。 id(create_foo()) == id(create_bar()) 的结果未定义。

      例子:

      >>> id([])     #the list object is discarded when id() returns
      39733320L
      >>> id([]) #a new, unrelated object is created (and discarded, too)
      39733320L #its id can happen to be the same
      >>> id([[]])
      39733640L #or not
      >>> id([])
      39733640L #you never really know

由于上述比较 id 时的安全要求,保存 id 而不是对象不是很有用,因为您必须保存对对象本身的引用无论如何 - 以确保它保持活力。也没有任何性能提升:is implementation is as simple as comparing pointers .


最后,作为内部优化(和实现细节,因此实现和版本之间可能有所不同),CPython 重用了一些常用的不可变类型的简单对象。在撰写本文时,这包括 small integerssome strings .因此,即使您从不同的地方获取它们,它们的 id 也可能一致。

这并没有(技术上)违反上述 id() 文档的唯一性 promise :重用对象在所有重用过程中保持事件状态。

这也没什么大不了的,因为两个变量是否指向同一个对象只是实际知道对象是否可变:if two variables point to the same mutable object, mutating one will (unexpectedly) change the other, too .不可变类型没有这个问题,因此对于它们来说,两个变量指向两个相同的对象还是指向同一个对象都没有关系。


1有时,这称为“未命名表达式”。

关于python - id() 与 `is` 运算符。比较 `id` 是否安全?同样的 `id`是不是代表同一个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52268343/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com