are they any good patterns for “freezing” a Python...
# development
f
are they any good patterns for “freezing” a Python class? context: I wrote code to construct a trie and, during the construction process, the nodes need to be mutable but in order to work with the engine they need to be immutable and hashable. I’m thinking just a “frozen” flag to prevent mutation. Would that be sufficient to use it with the engine?
h
all the engine technically requires is
__hash__
. But to not improperly memoize, in practice, it should also be immutable This is the idea behind
@frozen_after_init
decorator
f
I need to be able to insert trie nodes even after
__init__
and then freeze the whole data structure at once
the alternative would be to use a dictionary and check the dictionary for each potential prefix of a Java package path, but the trie allows one traversal to handle all of it
but the complication is this need to make sure it is immutable and hashable after the trie is constructed
seems like not worth the effort
f
I usually use the builder pattern for something like this, where I give a mutable builder object a method to return a frozen immutable version once we're done with the building process. It works well unless there's some reason that the mutable and immutable thing absolutely need to be the same type
👍 2
f
they don’t need to be the same type, but adding a builder type (versus just freezing) just complicates this code greatly, this is a graph data structure, so builder pattern seems equivalent to just asking the data structure to freeze itself and returning a frozen version. s/freeze/build/. but it would let me swap in FrozenDict in place of the mutable `dict`’s necessary during graph construction.
just using a single dictionary seems much less work than either freezing or builder pattern
h
We use that pattern of using
OrderedSet
then freezing into
FrozenOrderedSet
. Same with dict and
FrozenDict
, or
list -> tuple
So long as the `@rule`'s boundary is frozen, it's fine to mutate in the body
w
to be clear: you don’t need
__hash__
unless you will be used as parameter in a
Get
👍 1
you do need equality though.