Как сделать хемо замороженный экземпляр класса данных? - PullRequest
1 голос
/ 17 апреля 2019

При определении класса данных с помощью frozen=False (поведение по умолчанию), а затем создании экземпляра объекта этого класса, есть ли способ сделать этот объект хэшируемым?

Зачем мне это нужно?

До Python 3.7 я использовал именованные кортежи вместо классов данных и использовал для поиска дубликатов, используя set(), но я больше не могу его использовать. Я не хочу использовать frozen=True для классов данных по другим причинам.

1 Ответ

2 голосов
/ 17 апреля 2019

Для этого есть параметр:

@dataclass(unsafe_hash=True)
class Whatever:
    ...

Возможно, вам следует использовать frozen=True.Если вам нужно обновить атрибуты в замороженном экземпляре класса данных, вы можете использовать dataclasses.replace для создания нового объекта:

new_thing = dataclasses.replace(old_thing, var=new_val)

Вы также можете использовать изменяемый экземпляр класса данных и dataclasses.astuple, чтобы получить кортеж, когда вам нужно что-то хэшируемое.Но будьте осторожны - у astuple странное поведение при копировании, поэтому вы можете получить поведение, подобное следующему:

In [1]: import dataclasses

In [2]: @dataclasses.dataclass
   ...: class Foo:
   ...:     a: object
   ...:     b: object
   ...:     

In [3]: x = object()

In [4]: a = Foo(x, x)

In [5]: b = dataclasses.astuple(a)

In [6]: b[0] is b[1]
Out[6]: False

In [7]: b[0] is x
Out[7]: False

In [8]: a == a
Out[8]: True

In [9]: dataclasses.astuple(a) == dataclasses.astuple(a)
Out[9]: False
...