有没有描述如何__cmp__工作在Python 2中的字典对象?

我一直试图做一个inheritance自UserDict.DictMixin ,支持不可哈希键的dict子类。 性能不是一个问题。 不幸的是,Python通过尝试从子类创build一个dict对象来实现DictMixin的一些function。 我可以自己实现这些,但是我被卡在__cmp__

我无法find内置的__cmp__为dict类所使用的逻辑的简洁描述。

如果你问如何比较字典的作品,这是这样的:

  • 要比较字典A和B,首先比较它们的长度。 如果不相等,则返回cmp(len(A),len(B))。
  • 接下来,在A中find关键字adiff,这个adiff not in B or A[adiff] != B[adiff]的最小关键字。 (如果没有这样的密钥,那么这些字典是相同的。)
  • 另外findB中bdiff not in A or A[bdiff] != B[bdiff]的最小密钥bdiff。
  • 如果adiff!= bdiff,则返回cmp(adiff,bdiff)。 否则返回cmp(A [adiff],B [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]) 

这是从dictobject.c中的2.6.3实现转换而来的。

另一种方法是使用集合包中的映射ABC。 它在2.6以上是可用的。 你只是inheritance了collections.Mapping和实现__getitem__ __iter____iter__ __contains____iter__方法。 你得到一切免费。

这里有一个关于__cmp__的描述,但是我认为重要的是要注意__cmp__只有在没有定义“丰富比较”的方法时才会使用,比如__lt____eq__ 。 而且,在Python3中,__cmp__被从语言中删除。 所以也许完全避免__cmp__ ,只是定义__lt____eq__