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

我正在与我的一位同事争论,是否所有的 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.

相关文章

功能概要:(目前已实现功能)公共展示部分:1.网站首页展示...
大体上把Python中的数据类型分为如下几类: Number(数字) ...
开发之前第一步,就是构造整个的项目结构。这就好比作一幅画...
源码编译方式安装Apache首先下载Apache源码压缩包,地址为ht...
前面说完了此项目的创建及数据模型设计的过程。如果未看过,...
python中常用的写爬虫的库有urllib2、requests,对于大多数比...