In Python, "frozen" means an object cannot be modified. For example, consider set and frozenset:

>>> s = set((1, 2, 3))
>>> s
{1, 2, 3}
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> fs = frozenset((1, 2, 3))
>>> fs
frozenset({1, 2, 3})
>>> fs.add(4)
...
AttributeError: 'frozenset' object has no attribute 'add'

Likewise, creating a dataclass with frozen=True means its instances are frozen and cannot be changed.

Be aware that frozen only applies to the dataclass instance itself – a frozen dataclass can contain mutable items such as lists, and a regular dataclass can contain frozen/immutable items such as tuples.


The point of frozen objects is to avoid accidental modification, and to guarantee a consistent value.

  • The former is advantageous to avoid bugs. When an object is not intended to be modified, making it frozen reveals accidental modification via an immediate error.
  • The latter allows use as immutable object, for example the keys of a dict. A frozen dataclass is by default hashable and suitable as a dict key.
from dataclasses import dataclass

@dataclass(frozen=True)
class Frozen:
    x: int
    y: int

named_points = {Frozen(0, 0): "Origin"}

Note that hashability does not just depend on the dataclass but is recursive – a frozen dataclass containing a list is not hashable, because the list is not hashable.

Answer from MisterMiyagi on Stack Overflow
Top answer
1 of 3
10

Well, you can do it by directly modifying the __dict__ member of the instance modifying the attribute using object.__setattr__(...)1, but why??? Asking specifically for immutable and then making it mutable is... indecisive. But if you must:

from dataclasses import dataclass

@dataclass(frozen=True)
class Foo:
    id: str
    name: str
    def strip_id(self):
        object.__setattr__(self, 'id', None)

foo=Foo(10, 'bar')

>>> foo
Foo(id=10, name='bar')
>>> foo.strip_id()
>>> foo
Foo(id=None, name='bar')

Any way of doing this is probably going to seem hacky... because it requires doing things that are fundamentally the opposite of the design.

If you're using this as a signal to other programmers that they should not modify the values, the way that is normally done in Python is by prefixing the variable name with a single underscore. If you want to do that, while also making the values accessible, Python has a builtin module called property, where (from the documentation) "typical use is to define a managed attribute":

from dataclasses import dataclass

@dataclass
class Foo:
    _name: str
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self, value):
        self._name = value
    @name.deleter
    def name(self):
        self._name = None

Then you can use it like this:

>>> f=Foo()
>>> f.name = "bar"
>>> f.name
'bar'
>>> f._name
'bar'
>>> del f.name
>>> f.name
>>> f._name

The decorated methods hide the actual value of _name behind name to control how the user interacts with that value. You can use this to apply transformation rules or validation checks to data before it is stored or returned.

This doesn't quite accomplish the same thing as using @dataclass(frozen=True), and if you try declaring it as frozen, you'll get an error. Mixing frozen dataclasses with the property decorator is not straightforward and I have not seen a satisfying solution that is concise and intuitive. @Arne posted this answer, and I found this thread on GitHub, but neither approach is very inspiring; if I came across such things in code that I had to maintain, I would not be very happy (but I would be confused, and probably pretty irritated).


1: Modified as per the answer by @Arne, who observed that the internal use of a dictionary as the data container is not guaranteed.

2 of 3
5

As a slight improvement over Z4-tier's solution, please use object.__setattr__ instead of self.__dict__ to manipulate attributes of a frozen dataclass. The fact that classes use a dictionary to store their attributes is just the default behavior, and dataclasses in particular will regularly use __slots__ instead because it reduces the memory footprint.

from dataclasses import dataclass

@dataclass(frozen=True)
class Foo:
    id: str
    name: str

    def strip_id(self):
        object.__setattr__(self, 'a', None)   
Discussions

Static-only `frozen` data classes (or other ways to avoid runtime overhead) - Typing - Discussions on Python.org
Making a Python data class frozen incurs a runtime performance penalty. There is of course an explanation for it, but the overall behaviour is a little counterintuitive – as a frozen data class can do less than its mutable counterpart. Immutability is a very useful property in practical software ... More on discuss.python.org
🌐 discuss.python.org
1
February 26, 2024
Idiomatic way to create a frozen + mutable dataclass pair?
A mutable dataclass is easy: @dataclasses.dataclass class Mutable_Foo: ham: str eggs: int A frozen dataclass is easy: @dataclasses.dataclass(frozen=True) class Frozen_Foo: ham: str eggs: int But I frequently want to use both Mutable_Foo and Frozen_Foo in the same codebase, with exactly the ... More on discuss.python.org
🌐 discuss.python.org
0
November 29, 2024
frozen dataclass inheritance is not strictly checked in multiple inheritance
The dataclass inheritance hierarchy is supposed to require all classes to be either frozen or non frozen, this works properly for checking that an unfrozen class does not inherit from any frozen classes, but it allows frozen classes to inherit from unfrozen ones as long as there's at least ... More on github.com
🌐 github.com
5
September 14, 2023
Dataclasses freezing specific fields should be possible - Ideas - Discussions on Python.org
it is common in python to make ... to dataclasses but the problem with dataclasses is that they don’t support specific frozen field, in dataclasses its all frozen or noth...... More on discuss.python.org
🌐 discuss.python.org
5
August 4, 2024
🌐
TestDriven.io
testdriven.io › tips › 671b59e7-ba72-4201-82d4-473c8e594c55
Tips and Tricks - Semi-immutable Python objects with frozen dataclasses | TestDriven.io
You can freeze instances of a class decorated with dataclass by setting frozen to True. https://docs.python.org/3/library/dataclasses.html#frozen-instances
🌐
Medium
noklam-data.medium.com › how-to-achieve-partial-immutability-with-python-dataclasses-or-attrs-0baa0d818898
How to achieve Partial Immutability with Python? dataclasses or attrs? | by Nok Chan | Medium
March 28, 2024 - This assume you already understand ... but WHICH libraries you may want to choose. ... With dataclasses, you can set frozen=True to ensure immutablilty....
🌐
Plain English
plainenglish.io › home › blog › python › why and how to write frozen dataclasses in python
Why and How to Write Frozen Dataclasses in Python
February 22, 2022 - Then we will transform it into a frozen class and discuss the difference. So, we create a Bank Account so that we can add or block some amount. It is extremely simple and there is no need to explain it: from dataclasses import dataclass from decimal import Decimal @dataclass class Account: amount: Decimal blocked: Decimal def add_amount(self, amount: Decimal) -> None: self.amount += amount def block_amount(self, amount: Decimal) -> None: if amount > self.amount: raise ValueError("Insufficient balance") self.blocked += amount @property def available_amount(self) -> Decimal: return self.amount - self.blocked
Find elsewhere
🌐
Python.org
discuss.python.org › typing
Static-only `frozen` data classes (or other ways to avoid runtime overhead) - Typing - Discussions on Python.org
February 26, 2024 - Making a Python data class frozen incurs a runtime performance penalty. There is of course an explanation for it, but the overall behaviour is a little counterintuitive – as a frozen data class can do less than its mutable counterpart.
🌐
Python.org
discuss.python.org › python help
Idiomatic way to create a frozen + mutable dataclass pair? - Python Help - Discussions on Python.org
November 29, 2024 - A mutable dataclass is easy: @dataclasses.dataclass class Mutable_Foo: ham: str eggs: int A frozen dataclass is easy: @dataclasses.dataclass(frozen=True) class Frozen_Foo: ham: str eggs: int But I frequently …
🌐
GitHub
github.com › python › cpython › issues › 109409
frozen dataclass inheritance is not strictly checked in multiple inheritance · Issue #109409 · python/cpython
September 14, 2023 - Bug report Bug description: import dataclasses @dataclasses.dataclass class NotFrozen: pass @dataclasses.dataclass(frozen=True) class Frozen: pass @dataclasses.dataclass(frozen=True) class Child(NotFrozen, Frozen): pass The dataclass inh...
Author   Batman-q96
🌐
Rednafi
rednafi.com › python › statically enforcing frozen data classes in python
Statically enforcing frozen data classes in Python | Redowan's Reflections
January 4, 2024 - You can use @dataclass(frozen=True) to make instances of a data class immutable during runtime. However, there’s a small caveat - instantiating a frozen data class is slightly slower than a non-frozen one.
🌐
Python.org
discuss.python.org › ideas
Dataclasses freezing specific fields should be possible - Ideas - Discussions on Python.org
August 4, 2024 - it is common in python to make some of our class fields read only after initialization commonly by using the property decorator class Person: def __init__(self, name: str, age: int) -> None: self._name = name self.age = age @property def name(self) -> str: return name but writing many class by hand is tedious, so we switch to dataclasses but the problem with dataclasses is that they don’t support specific frozen field, in dataclasses its all frozen or noth...
🌐
GitHub
github.com › python › mypy › issues › 14857
`Cannot inherit frozen dataclass from a non-frozen one` error when using pydantic `frozen=True` · Issue #14857 · python/mypy
March 8, 2023 - Bug Report Specifying frozen=True as model class kwargs for pydantic models causes the following error to be emitted from mypy: Cannot inherit frozen dataclass from a non-frozen one To Reproduce Install pydantic and mypy: pip install pyd...
Author   johnnyleitrim
🌐
Python Morsels
pythonmorsels.com › customizing-dataclass-initialization
Customizing dataclass initialization - Python Morsels
October 18, 2024 - And we still can't directly assign to any of the attributes on this new dataclass because it's frozen, which is exactly what we want: >>> r.width = 5 Traceback (most recent call last): File "<python-input-3>", line 1, in <module> r.width = 5 ^^^^^^^ File "<string>", line 17, in __setattr__ dataclasses.FrozenInstanceError: cannot assign to field 'width'
🌐
Medium
elshad-karimov.medium.com › pythons-dataclasses-replace-a-hidden-gem-for-immutable-data-handling-e10a82f6260b
Python’s dataclasses.replace() – A Hidden Gem for Immutable Data Handling! 🚀🐍 | by Elshad Karimov | Medium
March 26, 2025 - from dataclasses import dataclass @dataclass(frozen=True) class User: name: str age: int country: str user1 = User(name="Alice", age=30, country="USA") # ❌ This will fail since the dataclass is frozen # user1.age = 31 # ERROR: dataclasses.FrozenInstanceError
🌐
GitHub
github.com › ericvsmith › dataclasses › issues › 150
dataclass with `frozen=True` with `init=False` can't be instantiated · Issue #150 · ericvsmith/dataclasses
October 14, 2019 - Creating a dataclass that has frozen=True and a field with init=False makes a class that throws a dataclasses.FrozenInstanceError: cannot assign to field 'a_field' error when attempting to ...
Author   DBCerigo
🌐
Python Forum
python-forum.io › thread-43340.html
change dataclass to frozen at runtime
October 5, 2024 - I'm working with a dataclass that is code-generated by a tool I do not control: @dataclass class Concern: id: ConcernIDNote that the dataclass is not declared as frozen. I need this class to be frozen for the sake of Hashability, so I would like...
🌐
Python.org
discuss.python.org › python help
Frozen Dataclass and inheritance - Python Help - Discussions on Python.org
July 25, 2025 - I try to figure out what’s happening when a frozen dataclass is inherited. Let’s create a frozen dataclass: from dataclasses import dataclass @dataclass(frozen=True) class Base: a: int = 0 b: int = 0 base = B…
🌐
Pydantic
docs.pydantic.dev › latest › api › dataclasses
Pydantic Dataclasses - Pydantic Validation
dataclass( *, init: Literal[False] = False, repr: bool = True, eq: bool = True, order: bool = False, unsafe_hash: bool = False, frozen: bool = False, config: ConfigDict | type[object] | None = None, validate_on_init: bool | None = None, kw_only: ...
🌐
Python
docs.python.org › 3 › library › dataclasses.html
dataclasses — Data Classes
3 weeks ago - Raised when an implicitly defined __setattr__() or __delattr__() is called on a dataclass which was defined with frozen=True.