我的论点是,由于我们无法比较两个表达式的相等性,因此不应允许散列.例如,表达式'(x)’和'(1 * x)’可能比较相等,而’sqrt(x * x * x)’和’abs(x)* sqrt(x)’可能不相等.因此,’hash()’在使用符号表达式调用时应该抛出错误.
他的论点是你应该能够将所有类用作词典和集合中的键.因此,它们也必须是可以清洗的. (我现在把话放在嘴里,他会更好地解释它.)
谁是对的?如果你试图哈希它们是否是unpythonic或没有抛出错误的类?
解决方法
但事实上,在我看来,你所定义的平等概念是一种非常不同的平等概念,而不是Python中正常的平等概念.可持续性的基本要求是,如果两个项目的评估相同,那么它们应该是完全可互换的.虽然你的两个表达式对象可能被评估为“相等”,但我不确定它们是否可以互换!毕竟,5 5和8 2评估相同的结果,但它们不相同,是吗?鉴于这两个表达式,我怀疑很多人会希望它们在字典中散列到两个独立的分档中!
然而,如果不给予__eq__更传统的定义,那么这种行为将是困难的.正如文档所说,“Hashable objects which compare equal must have the same hash value”.因此,如果__eq__表示5 5和8 2相等,那么它们必须散列到相同的值.这意味着要使表达式像现在一样可以使用,你必须选择一个__hash__,它能够为所有评估为相等的表达式确定规范形式.这听起来非常难.
简而言之,如果这些表达式是不可变的,并且如果重新定义__eq__以返回True,如果表达式相同(比“相等”更强的要求),则应该没有问题使它们可以清除.另一方面,我认为不可变的不可变类型没有任何问题;并且我不建议在不重新定义__eq__的情况下尝试使表达式可哈希.
所以这一切都归结为你想以非常规方式定义__eq__的严重程度.我想总的来说,我会选择__eq__的传统定义,只是为了避免产生意外行为.毕竟,special cases aren’t special enough to break the rules.