【问题标题】:What are the semantics of the 'is' operator in Python?Python中'is'运算符的语义是什么?
【发布时间】:2010-03-13 14:28:49
【问题描述】:

is 运算符如何确定两个对象是否相同?它是如何工作的?我找不到它的文档。

【问题讨论】:

  • 类似于C中比较指针,或者Java中对象之间使用==
  • S.Lott:对不起,我不是文档系统方面的专家,看了几十篇文档,我无法找到确切的含义。

标签: python


【解决方案1】:

来自documentation

每个对象都有一个身份,一个类型 和一个值。对象的身份 一旦发生就永远不会改变 创建;你可能会认为它是 对象在内存中的地址。 “是” 运算符比较两个的身份 物体; id() 函数返回一个 表示其身份的整数 (目前实施为其 地址)。

这似乎表明它比较了参数的内存地址,尽管它说“你可能认为它是内存中的对象地址”这一事实可能表明特定的实现不是保证的;只有语义是。

【讨论】:

  • 特别是,我会假设小整数(具有相同的 id)实际上可能不会存储在内存中的任何特定位置。
  • CPython 比较内存地址,但这是一个实现细节,类似于 id() 返回的值。当我已经提到 id() 时,应该说在具有移动 GC 的实现上调用 id() 可能非常昂贵,所以应该避免调用它。
【解决方案2】:

Comparison Operators

通过比较引用的对象来查看操作数是否指向同一个对象。

>>> a = [1, 2]
>>> b = a
>>> a is b
True
>>> c = [1, 2]
>>> a is c
False

ca 不是同一个列表,因此is 关系为假。

【讨论】:

  • 但是!请注意,对于某些不可变对象,此 可能 有所不同。例如,a = 5; b = 5; a is b 返回 True,此时,在这台笔记本电脑上,在这个版本的 Python 上。你不能保证两个对象是不同的,因为它们是分开初始化的。
  • 确实,is 在 Python 中几乎唯一的应用是比较单例,例如 if foo is Nonesentinel = object() ... if bar is sentinel
  • @Just:您可以保证某些对象在单独初始化时是不同的,就像这个答案与列表一样,因为您必须知道@ 987654329@会修改c.
  • @Roger:我的意思是你并不总是知道 Python 会产生两个不同的对象,因为它们是分别初始化的。仅凭这一点还不足以保证区别。我想给 msw 的例子举一个反例,它们不同的,表明情况并非总是如此。是的,如果这对您很重要,您必须使用 is 来验证独特性,这就是我的观点。 :-)
【解决方案3】:

要添加到其他答案,您可以将a is b 视为is_(a, b) 工作:

def is_(a, b):
  return id(a) == id(b)

注意directly replacea is b不能和id(a) == id(b)一起使用,但上面的函数通过参数避免了这种情况。

【讨论】:

  • 刚刚偶然发现:你知道为什么直接替换不起作用,但通过函数就可以了吗?
猜你喜欢
  • 2013-08-18
  • 2011-06-11
  • 2015-05-28
  • 1970-01-01
  • 2019-09-12
  • 1970-01-01
  • 1970-01-01
  • 2015-10-29
  • 1970-01-01
相关资源
最近更新 更多