有没有描述如何__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__
。