代码之家  ›  专栏  ›  技术社区  ›  Björn Pollex

在eq中检查身份是否有意义?

  •  8
  • Björn Pollex  · 技术社区  · 14 年前

    在为类实现自定义相等函数时,首先检查标识是否有意义?一个例子:

    def __eq__(self, other):
        return (self is other) or (other criteria)
    

    当其他标准可能更昂贵时(例如,比较一些长字符串),这种情况很有趣。

    5 回复  |  直到 14 年前
        1
  •  3
  •   Jochen Ritzel    14 年前

    遗产:没有

    有道理吗:当然,为什么不呢?

    默认情况下不执行此类检查,如您在此处看到的:

    class bad(object):
        def __eq__(self, other):
            return False
    
    x = bad()
    print x is x, x==x # True, False
    
        2
  •  7
  •   Scott Griffiths    14 年前

    首先检查身份可能是一个非常合理的快捷方式,在平等方法中,您应该寻找好的快捷方式(对于平等和不平等),以便尽快返回。

    但是,从另一方面来说,如果你的平等测试成本很低,而且你在实践中不太可能将一个对象与它本身进行比较,那么这也可能是一个完全多余的检查。

    例如,如果可以通过比较一个或两个整数来衡量对象之间的相等性,那么这应该比身份测试更快,因此在比较所需的时间内 id 你知道全部答案了吗?记住,如果你检查身份和对象不一样 身份证件 (在大多数情况下可能是这样)那么你什么也得不到,因为你还需要做全面检查。

    因此,如果完全相等性检查不便宜,并且有可能将对象与自身进行比较,那么首先检查身份是一个好主意。


    请注意,默认情况下未执行检查的另一个原因是,对于具有相同标识的对象,将其作为非相等对象进行比较是非常合理的(尽管很少见),例如:

    >>> s = float('nan')
    >>> s == s
    False
    
        3
  •  2
  •   Chris B.    14 年前

    在类中实现自定义相等时,可以自己决定是否首先检查标识。这完全取决于你。注意,在python中,决定 __eq__ __ne__ 将为给定参数返回相同的值;因此可以定义相等,这样标识就不是快捷方式。

    这当然是一种速度改进,尽管其中有多少取决于方法的复杂性。我通常不会在自定义类中费心,但我没有太多速度关键的代码(在我这样做的地方,对象比较不是热点)。

    对于我的大多数对象,相等方法如下:

    def __eq__(self, o):
        try:
            return self.x == o.x and self.y == o.y
        except AttributeError:
            return False
    

    我可以很容易地添加 if self is o: return True 在方法的开头进行检查。

    还记得重写 __hash__ 如果你重写 爱斯克 否则你会有奇怪的行为 set S和 dict S.

        4
  •  1
  •   PaulMcG    14 年前

    几年前我在comp.lang.python上问了一个类似的问题- here is the thread . 当时的结论是,如果您对对象本身进行了许多相等性测试,或者您的其他相等性测试逻辑很慢,那么前面的身份测试是值得的。

        5
  •  0
  •   Sjoerd    14 年前

    这只是出于性能原因。

    在我在爪哇工作的一个编程工作中,总是这样做,即使它没有改变任何功能。