Callable
fields: List[InputFieldRM]
extra: FigureExtra
Мне нужно, чтобы объект был хешируемым, но из-за того, что в fields лежит список, то он таким не является. При этом, мне не хочется заменять список на тапл, поскольку не очень удобно.
Как лучше всего сделать его хешируемым?
Сделать InitVar, в котором бы лежал список, а в пост ините преобразовать в тапл? Или хранить и тапл и список?
Пометь секвенс, а в постините сделай тапл
Стоп, для хешируемости нужен же, чтобы датакласс был frozen, а тогда в постините я не могу заменять атрибуты без магии
Ну можно сделать dirty hash, а для исключения изменения пропертей навешать
Может, инит вар проще будет?
В данном кейсе я заменил все список на тапл, но появилась идея, как в таких случаях можно поступать иногда. Внутри FieldRM есть metadata: Mapping. Можно было сделать HashableMapping протокол, но стандартные маппинги никогда хеш не реализуют. Так что я просто выкинул это поле из хеша (благо, датаклассы так позволяют). В данном случае на коллизиях это почти никак не скажется
Нет, а зачем? Если у поля разная метадата, то это разные поля. Но у FieldRM с разной метадатой и со всеми другими одинаковыми полями, будет одинаковый хеш (коллизия), что не страшно
так если у тебя хэш сохранился, но на равенство перестало работать, разве будет словарь корректно это обслуживать?
Не очень понял вопрос
для какой цели тебе хэшируемость?
хотя вот так если логически рассуждать, вроде должен
Для того, чтобы использовать в коллекциях, предоставляющих лукап за O(1). У меня одинаковые объекты имеют одинаковый хеш, но разные объекты могут иметь один хеш, так что контракт сохраняется
class A: def __init__(self, x): self.data = [] self.x = x def __hash__(self): return self.x def __eq__(self, other): return self.data == other.data and self.x == other.x a1 = A(1) a2 = A(1) x = {a1: "hello"} print(x[a2]) a1.data.append(0) print(x[a2]) для меня это немного неожиданно, но наверно допустимо
Обсуждают сегодня