我仍然使用python 2.x的99%以上,但我正在努力思考切换的那一天。
所以,我知道在python3.x中不再支持在没有自然排序的异构类型上使用比较运算符(小于/大于或等于) - 而不是某些一致(但是任意)结果我们提出了TypeError
。我看到了这个逻辑,甚至大多数人都认为它是一件好事。一致性和拒绝猜测是一种美德。
但是,如果您基本上想要python2.x行为怎么办?获得它的最佳方法是什么?
为了好玩(或多或少)我最近实现了一个Skip List,一个保持元素排序的数据结构。我想在数据结构中使用异构类型作为键,并且当我遍历数据结构时,我必须将键相互比较。 python2.x的比较方式使得这非常方便 - 您可以在具有自然顺序的元素中获得可理解的顺序,并在那些不具有自然顺序的元素中获得某些顺序。
一直使用类似(type(obj).__name__, obj)
的排序/比较键,其缺点是不会交错具有自然顺序的对象;您在float
之前将所有int
群集在一起,并且str
派生的类与您的str
分开。
我想出了以下内容:
import operator
def hetero_sort_key(obj):
cls = type(obj)
return (cls.__name__+'_'+cls.__module__, obj)
def make_hetero_comparitor(fn):
def comparator(a, b):
try:
return fn(a, b)
except TypeError:
return fn(hetero_sort_key(a), hetero_sort_key(b))
return comparator
hetero_lt = make_hetero_comparitor(operator.lt)
hetero_gt = make_hetero_comparitor(operator.gt)
hetero_le = make_hetero_comparitor(operator.le)
hetero_ge = make_hetero_comparitor(operator.gt)
有更好的方法吗?
我怀疑有人可以构建一个可以搞砸的角落案例 - 你可以将A类型与B类型进行比较,然后输入A到C类型,但是当比较时B和C引发TypeError
的情况,你最终可能会出现像a > b
,a < c
和b > c
这样不合逻辑的内容(因为他们的类名如何排序)。我不知道你在实践中遇到这种情况的可能性有多大。
答案 0 :(得分:0)
您可以尝试使对象/类型正确排序的方法,而不是“修复”python 3.x社区在全局范围内“修复”的内容。我对python 3.x并不熟悉,但我确信仍然有一个__cmp__
方法可以在子类中重写并修复,以便比较可行。您可以将其与id()
结合使用来恢复旧的破坏行为(根据内存中的位置id()
进行排序,如果我的记忆正确地为我服务的话)。