微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

拥有不可清洗的课程是不是一般的吗?

我正在与我的一位同事争论,是否所有的 Python类都需要是可以清除的.我们这个类包含符号表达式(类似于SymPy).

我的论点是,由于我们无法比较两个表达式的相等性,因此不应允许散列.例如,表达式'(x)’和'(1 * x)’可能比较相等,而’sqrt(x * x * x)’和’abs(x)* sqrt(x)’可能不相等.因此,’hash()’在使用符号表达式调用时应该抛出错误.

他的论点是你应该能够将所有类用作词典和集合中的键.因此,它们也必须是可以清洗的. (我现在把话放在嘴里,他会更好地解释它.)

谁是对的?如果你试图哈希它们是否是unpythonic或没有抛出错误的类?

解决方法

在这里看到的问题是你正在使用两种不同的平等概念.如果我正确理解你的评论,你已经覆盖了__eq__以返回一个将两个参数组合成==的表达式.如果所述表达式的计算结果为True(在某种意义上),那么这两个表达式是相等的;如果你的表达式类也以这样的方式实现__nonzero__(__ bool__在Python 3中),如果表达式为真,则__nonzero__返回True,那么表面看起来似乎应该可以正常工作.

但事实上,在我看来,你所定义的平等概念是一种非常不同的平等概念,而不是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.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐