【问题标题】:does pythons keyword "in" check for "is" or for "=="pythons关键字“in”是否检查“is”或“==”
【发布时间】:2019-02-25 13:58:40
【问题描述】:

关键字in 通常在python 中检查什么?平等、身份,还是别的什么?

例子:

假设我有两个类 X 和 Y 使用不同的 __eq__ 运算符

class X:
  def __eq__(self,other):
    return False

class Y:
  def __eq__(self,other):
    return True

现在我可以了

a = X()
b = a
k = [a]
b in k # -> True

这建议对我进行身份检查。
但我也可以

c = Y()
d = Y()
c is d # -> False
l = [d]
c in l # -> True

这表明检查是否相等。我想出的唯一理论是它首先检查身份,如果不是这样,然后检查是否相等。对吗?

【问题讨论】:

  • 是的。它检查身份,然后检查相等性。
  • 如果a is bTruea == bFalse,您的== 将完全损坏。根据定义,平等是自反的:x == x 代表所有 x
  • @chepner 那是精神分裂症对象模式……
  • @chepner 有 x!=x 的对象。例如。 float('nan') 不等于自身。
  • in 本身使用都不使用;见docs.python.org/3/reference/…

标签: python python-3.x identity equality


【解决方案1】:

检查 list 的包含情况等同于查找每个元素的同一性或相等性。

来自the documentation

对于 list、tuple、set、frozenset、dict 或 collections.deque 等容器类型, 表达式x in y 等价于any(x is e or x == e for e in y)

(需要注意的是,基于散列的容器中的对象(如集合)必须具有与其相等定义一致的散列实现。)

对于用户定义的容器类型,in 的行为由__contains__ 方法确定。

【讨论】:

  • 当然,除非容器定义了 __contains__ 方法,例如用于首先测试哈希码...set 等也应该是这种情况,因此文档不能真正准确,对吧?
  • 或者如果它定义了__getitem__ FWIW。
  • 你也可以通过定义__contains__ = lambda *args: True来享受罗素悖论的乐趣。
  • @khelwood 您可能想要更新您的答案,以明确此摘录仅适用于某些内置容器...
  • @khelwood 错误...确实,我的错,我没有发现它。但是你可能应该让它更突出(例如粗体文本......)xD
【解决方案2】:

真正的答案是,in 本身不做任何测试——这取决于容器(表达式中 in 之后的对象)的实现。 in 实际上将调用 container.__contains__(obj)(如果已定义),否则将调用 container.__getitem__(obj),并返回结果。容器如何实现测试(身份、平等、基于月相和船长生日的神秘算法)是容器的关注点。

【讨论】:

  • 您可以添加“hashcode”作为另一个(实际)遏制测试的示例。
猜你喜欢
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多