Есть ли описание того, как работает __cmp__ для объектов dict в Python 2?

Я пытался создать подкласс dict , унаследованный от UserDict.DictMixin , который поддерживает не хэшируемые ключи. Производительность не проблема. К сожалению, Python реализует некоторые функции из DictMixin , пытаясь создать объект dict из подкласса. Я могу реализовать это сам, но я застрял на __ cmp __ .

Я не могу найти краткое описание логики, используемой встроенным __ cmp __ для класса dict.

21
задан l4mpi 11 March 2014 в 19:00
поделиться

3 ответа

Если вы спрашиваете, как работает сравнение словарей, то вот так:

  • Чтобы сравнить словари A и B, сначала сравните их длины. Если они не равны, то верните cmp(len(A), len(B)).
  • Затем найдите ключ adiff в A, который является наименьшим ключом, для которого adiff нет в B или A[adiff] != B[adiff]. (Если такого ключа нет, то дикты равны.)
  • Также найдите наименьший ключ bdiff в B, для которого bdiff не в A или A[bdiff] != B[bdiff].
  • Если adiff != bdiff, то возвращаем cmp(adiff, bdiff). Иначе return 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])

Это переведено из реализации 2.6.3 в dictobject.c.

31
ответ дан 29 November 2019 в 21:12
поделиться

Альтернативой является использование Mapping ABC из пакета collections. Он доступен в версии 2.6 и выше. Вы просто наследуете от collections.Mapping и реализуете методы __getitem__, __contains__ и __iter__. Все остальное вы получаете бесплатно.

2
ответ дан 29 November 2019 в 21:12
поделиться

Здесь есть описание __ cmp __ , но я думаю, что важно отметить, что __ cmp __ используется только в том случае, если методы «расширенного сравнения», такие как __ lt __ и __ eq __ не определены. Более того, в Python3 __ cmp __ удален из языка. Так что, возможно, полностью избегайте __ cmp __ и просто определите __ lt __ и __ eq __ .

0
ответ дан 29 November 2019 в 21:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: