python3中的异构比较

时间:2010-05-05 01:15:45

标签: python comparison

我仍然使用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 > ba < cb > c这样不合逻辑的内容(因为他们的类名如何排序)。我不知道你在实践中遇到这种情况的可能性有多大。

1 个答案:

答案 0 :(得分:0)

您可以尝试使对象/类型正确排序的方法,而不是“修复”python 3.x社区在全局范围内“修复”的内容。我对python 3.x并不熟悉,但我确信仍然有一个__cmp__方法可以在子类中重写并修复,以便比较可行。您可以将其与id()结合使用来恢复旧的破坏行为(根据内存中的位置id()进行排序,如果我的记忆正确地为我服务的话)。

相关问题