在比较值之前比较使用`==`比较身份?

Pet*_*ood 3 python identity equality-operator

如果我使用比较两个变量==,Python会比较身份,如果它们不相同,那么比较值?

例如,我有两个指向同一个字符串对象的字符串:

>>> a = 'a sequence of chars'
>>> b = a
Run Code Online (Sandbox Code Playgroud)

这是比较值,还是只比较ids?:

>>> b == a
True
Run Code Online (Sandbox Code Playgroud)

首先比较身份是有意义的,我想是这样的,但我还没有在文档中找到任何支持这一点的东西.我得到的最接近是这样:

x==y 电话 x.__eq__(y)

这并没有告诉我在打电话之前是否做了什么x.__eq__(y).

jon*_*rpe 6

对于用户定义的类实例,is用作后备 - 其中默认__eq__值未被覆盖,a == b被评估为a is b.这可确保比较始终具有结果(除非在NotImplemented明确禁止比较的情况下).

这是(有点倾斜 - Sven Marnach的好位置)在数据模型文档中提到的(强调我的):

用户定义的类默认具有__eq__()__hash__()方法; 与它们相比,所有对象都比较不相等(除了它们自己)x.__hash__()返回一个适当的值,这x == y意味着它x is yhash(x) == hash(y).


您可以按如下方式演示:

>>> class Unequal(object):
    def __eq__(self, other):
        return False


>>> ue = Unequal()
>>> ue is ue
True
>>> ue == ue
False
Run Code Online (Sandbox Code Playgroud)

所以__eq__必须先调用id,但是:

>>> class NoEqual(object):
    pass

>>> ne = NoEqual()
>>> ne is ne
True
>>> ne == ne
True
Run Code Online (Sandbox Code Playgroud)

所以id必须在__eq__未定义的地方调用.


您可以在CPython实现中看到这一点,其中指出:

/* If neither object implements it, provide a sensible default
   for == and !=, but raise an exception for ordering. */
Run Code Online (Sandbox Code Playgroud)

"合理的默认"实行的是指针的C级相等比较vw,这将返回他们是否指向同一个对象.

  • 回退到用户定义类的对象标识不是CPython实现细节.它是语言规范的一部分,但在[一个稍微出乎意料的地方](https://docs.python.org/2/reference/datamodel.html#object.__hash__)中有记载. (2认同)