Python 2中字典对象__cmp__的工作原理描述吗?
我一直在尝试创建一个从 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实现中翻译过来的。