Python 2中字典对象__cmp__的工作原理描述吗?

22 投票
3 回答
8144 浏览
提问于 2025-04-16 02:47

我一直在尝试创建一个从 UserDict.DictMixin 继承的 dict 子类,目的是支持不可哈希的键。性能不是我的主要考虑。不过,遗憾的是,Python 在 DictMixin 中实现了一些功能时,会尝试从这个子类创建一个字典对象。我可以自己实现这些功能,但我在 __cmp__ 这个部分遇到了困难。

我找不到关于内置 __cmp__ 在字典类中使用的逻辑的简洁描述。

3 个回答

0

这里有关于 __cmp__ 的介绍,具体可以查看 这个链接。不过我觉得最重要的是要知道,只有在没有定义“丰富比较”方法,比如 __lt__(小于)和 __eq__(等于)的情况下,__cmp__ 才会被使用。而且在 Python3 中,__cmp__ 已经被移除了。所以,可能完全不需要用到 __cmp__,只需要定义 __lt____eq__ 就可以了。

2

另一种选择是使用 collections 包中的 Mapping ABC。这个功能在 Python 2.6 及以上版本都可以用。你只需要从 collections.Mapping 继承,并实现 __getitem____contains____iter__ 这几个方法。其他的功能你就可以直接使用了。

34

如果你想知道字典(dict)是怎么比较的,过程是这样的:

  • 首先,比较字典A和字典B的长度。如果它们的长度不一样,就返回它们长度的比较结果。
  • 接下来,在字典A中找出一个最小的键(key),这个键要满足条件:要么它不在字典B里,要么字典A和字典B在这个键对应的值(value)上不相等。 如果找不到这样的键,说明两个字典是相等的。
  • 然后,在字典B中找出一个最小的键,条件同样是:要么它不在字典A里,要么字典A和字典B在这个键对应的值上不相等。
  • 如果找到的键adiff和bdiff不一样,就返回这两个键的比较结果。如果它们一样,就返回这两个键对应的值的比较结果。

用伪代码表示就是这样:

def smallest_diff_key(A, B):
    """return the smallest key adiff in A such that adiff not in B or A[adiff] != B[bdiff]"""
    diff_keys = [k for k in A if k not in B or A[k] != B[k]]
    return min(diff_keys)

def dict_cmp(A, B):
    if len(A) != len(B):
        return cmp(len(A), len(B))
    try:
        adiff = smallest_diff_key(A, B)
    except ValueError:
        # No difference.
        return 0
    bdiff = smallest_diff_key(B, A)
    if adiff != bdiff:
        return cmp(adiff, bdiff)
    return cmp(A[adiff], b[bdiff])

这段内容是从2.6.3版本的dictobject.c实现中翻译过来的。

撰写回答