Reputation: 11172
When defining a dataclass with frozen=False
(default behaviour), and then instantiating an object of this class, is there a way to make this object hashable?
Before Python 3.7, I used named tuples instead of dataclasses and I used to find duplicates using set()
, but I can't use it anymore.
I don't want to use frozen=True
on dataclasses for other reasons.
Upvotes: 6
Views: 1843
Reputation: 281683
There's a parameter for that:
@dataclass(unsafe_hash=True)
class Whatever:
...
You should probably use frozen=True
, though. If you need to update attributes on a frozen dataclass instance, you can use dataclasses.replace
to construct a new object:
new_thing = dataclasses.replace(old_thing, var=new_val)
You can also use a mutable dataclass instance and dataclasses.astuple
to get a tuple when you need something hashable. Watch out, though - astuple
has a bunch of weird copying behavior, so you can get behavior like the following:
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
Upvotes: 9