In Python 3.10+ you can use slots=True with a dataclass to make it more memory-efficient:

from dataclasses import dataclass

@dataclass(slots=True)
class Point:
    x: int = 0
    y: int = 0

This way you can set default field values as well.

Answer from Eugene Yarmash on Stack Overflow
🌐
Python
docs.python.org › 3 › library › dataclasses.html
dataclasses — Data Classes
3 weeks ago - It is an error to specify weakref_slot=True without also specifying slots=True. Added in version 3.11. fields may optionally specify a default value, using normal Python syntax: @dataclass class C: a: int # 'a' has no default value b: int = 0 # assign a default value for 'b'
Top answer
1 of 6
70

In Python 3.10+ you can use slots=True with a dataclass to make it more memory-efficient:

from dataclasses import dataclass

@dataclass(slots=True)
class Point:
    x: int = 0
    y: int = 0

This way you can set default field values as well.

2 of 6
56

2021 UPDATE: direct support for __slots__ is added to python 3.10. I am leaving this answer for posterity and won't be updating it.

The problem is not unique to dataclasses. ANY conflicting class attribute will stomp all over a slot:

>>> class Failure:
...     __slots__ = tuple("xyz")
...     x=1
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 'x' in __slots__ conflicts with class variable

This is simply how slots work. The error happens because __slots__ creates a class-level descriptor object for each slot name:

>>> class Success:
...     __slots__ = tuple("xyz")
...
>>>
>>> type(Success.x)
<class 'member_descriptor'>

In order to prevent this conflicting variable name error, the class namespace must be altered before the class object is instantiated such that there are not two objects competing for the same member name in the class:

  • the specified (default) value*
  • the slot descriptor (created by the slots machinery)

For this reason, an __init_subclass__ method on a parent class will not be sufficient, nor will a class decorator, because in both cases the class object has already been created by the time these functions have received the class to alter it.

Current option: write a metaclass

Until such time as the slots machinery is altered to allow more flexibility, or the language itself provides an opportunity to alter the class namespace before the class object is instantiated, our only choice is to use a metaclass.

Any metaclass written to solve this problem must, at minimum:

  • remove the conflicting class attributes/members from the namespace
  • instantiate the class object to create the slot descriptors
  • save references to the slot descriptors
  • put the previously removed members and their values back in the class __dict__ (so the dataclass machinery can find them)
  • pass the class object to the dataclass decorator
  • restore the slots descriptors to their respective places
  • also take into account plenty of corner cases (such as what to do if there is a __dict__ slot)

To say the least, this is an extremely complicated endeavor. It would be easier to define the class like the following- without a default value so that the conflict doesn't occur at all- and then add a default value afterward.

Current option: make alterations after class object instantiation

The unaltered dataclass would look like this:

@dataclass
class C:
    __slots__ = "x"
    x: int

The alteration is straightforward. Change the __init__ signature to reflect the desired default value, and then change the __dataclass_fields__ to reflect the presence of a default value.

from functools import wraps

def change_init_signature(init):
    @wraps(init)
    def __init__(self, x=1):
        init(self,x)
    return __init__

C.__init__ = change_init_signature(C.__init__)

C.__dataclass_fields__["x"].default = 1

Test:

>>> C()
C(x=1)
>>> C(2)
C(x=2)
>>> C.x
<member 'x' of 'C' objects>
>>> vars(C())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: vars() argument must have __dict__ attribute

It works!

Current option: a setmember decorator

With some effort, a so-called setmember decorator could be employed to automatically alter the class in the manner above. This would require deviating from the dataclasses API in order to define the default value in a location other than inside the class body, perhaps something like:

@setmember(x=field(default=1))
@dataclass
class C:
    __slots__="x"
    x: int

The same thing could also be accomplished through a __init_subclass__ method on a parent class:

class SlottedDataclass:
    def __init_subclass__(cls, **kwargs):
        cls.__init_subclass__()
        # make the class changes here

class C(SlottedDataclass, x=field(default=1)):
    __slots__ = "x"
    x: int

Future possibility: change the slots machinery

Another possibility, as mentioned above, would be for the python language to alter the slots machinery to allow more flexibility. One way of doing this might be to change the slots descriptor itself to store class level data at the time of class definition.

This could be done, perhaps, by supplying a dict as the __slots__ argument (see below). The class-level data (1 for x, 2 for y) could just be stored on the descriptor itself for retrieval later:

class C:
    __slots__ = {"x": 1, "y": 2}

assert C.x.value == 1
assert C.y.value == y

One difficulty: it may be desired to only have a slot_member.value present on some slots and not others. This could be accommodated by importing a null-slot factory from a new slottools library:

from slottools import nullslot

class C:
    __slots__ = {"x": 1, "y": 2, "z": nullslot()}

assert not hasattr(C.z, "value")

The style of code suggested above would be a deviation from the dataclasses API. However, the slots machinery itself could even be altered to allow for this style of code, with accommodation of the dataclasses API specifically in mind:

class C:
    __slots__ = "x", "y", "z"
    x = 1  # 1 is stored on C.x.value
    y = 2  # 2 is stored on C.y.value

assert C.x.value == 1
assert C.y.value == y
assert not hasattr(C.z, "value")

Future possibility: "prepare" the class namespace inside the class body

The other possibility is altering/preparing (synonymous with the __prepare__ method of a metaclass) the class namespace.

Currently, there is no opportunity (other than writing a metaclass) to write code that alters the class namespace before the class object is instantiated, and the slots machinery goes to work. This could be changed by creating a hook for preparing the class namespace beforehand, and making it so that an error complaining about the conflicting names is only produced after that hook has been run.

This so-called __prepare_slots__ hook could look something like this, which I think is not too bad:

from dataclasses import dataclass, prepare_slots

@dataclass
class C:
    __slots__ = ('x',)
    __prepare_slots__ = prepare_slots
    x: int = field(default=1)

The dataclasses.prepare_slots function would simply be a function-- similar to the __prepare__ method-- that receives the class namespace and alters it before the class is created. For this case in particular, the default dataclass field values would be stored in some other convenient place so that they can be retrieved after the slot descriptor objects have been created.


* Note that the default field value conflicting with the slot might also be created by the dataclass machinery if dataclasses.field is being used.

Discussions

When should I use __slots__ in a Python class, and what are the tradeoffs?
You lose the ability to add new ... Also worth noting: if you’re using dataclasses, you’ll need to explicitly enable slots via @DataClass(slots=True) (available in Python 3.10+).... More on github.com
🌐 github.com
4
3
July 30, 2025
Statically enforcing frozen data classes in Python
am i misunderstanding or is this just a performance hack? edit: whoa, no, it's worse, it's disabling runtime checks! the title is really misleading? shouldn't it be "disabling runtime frozen data classes if you really need an obscure speedup at the cost of more complex code" sorry if i've misunderstood, but this really seems like something newbs need warning against. More on reddit.com
🌐 r/Python
24
36
January 4, 2024
Dataclasses and non-dataclasses inheritance
My codebase included (over many modules) code like: class C0: pass @dataclass class DC2: my_field: bool = True class C1(C0, DC2): # original state pass And lo it was good: print(len(C1.__dataclass_fields__)) # 1, life is good But then I tried turning the non-dataclass parent into a dataclass: ... More on discuss.python.org
🌐 discuss.python.org
0
April 19, 2025
Full support for slots in dataclasses
Can you elaborate why someone would want slots in dataclasses? Or slots in general? More on reddit.com
🌐 r/Python
5
18
January 30, 2023
🌐
Hacker News
news.ycombinator.com › item
Reasons to use dataclass(slots=True) instead of TypedDict - Faster attribute acc... | Hacker News
October 17, 2024 - For me it’s mostly about .attribute being more in line with the rest of the language. Kwargs aside, I find overuse of dicts to clunky in Python · https://wiki.python.org/moin/UsingSlots
🌐
Medium
doziestar.medium.com › speed-upyour-python-classes-with-slot-454e0655a816
Speed Up Your Python classes with slot | by Chidozie C. Okafor | Medium
May 8, 2022 - Usage of __slots__ reduce the wastage of space and speed up the program by allocating space for a fixed amount of attribute · To create a slot, all we need to do is to add __slots__ field or slots=True if we are using dataclass...
🌐
Plain English
python.plainenglish.io › supercharging-python-classes-with-dataclass-and-slots-3557f8b292d4
Supercharging Python Classes with dataclass and Slots | by Khushiyant | Python in Plain English
November 13, 2023 - In the world of Python, when you need to create classes with lots of attributes, it can become cumbersome to write out all the boilerplate code for __init__, __repr__, and other special methods. Python's dataclass decorator is here to simplify your life and make your code more readable. In this blog, we'll explore how to combine dataclass with slots to create efficient and readable classes, using practical code examples.
Find elsewhere
🌐
Towards Data Science
towardsdatascience.com › home › latest › should you use slots? how slots affect your class, and when and how to use them
Should You Use Slots? How Slots Affect Your Class, and When and How to Use Them | Towards Data Science
March 5, 2025 - It’s even easier with dataclasses, just add a single argument to the @dataclass decorator. Just define your dataclass like below: @dataclasses.dataclass(slots=True) class Person: name: str
🌐
The New Stack
thenewstack.io › home › python dataclasses: a complete guide to boilerplate‑free objects
Python Dataclasses: A Complete Guide to Boilerplate‑Free Objects - The New Stack
October 9, 2025 - Dataclasses offer several more advanced features to improve memory efficiency, code clarity and integration with modern Python features. In Python 3.10+, you can use slots=True to tell the dataclass to predefine its attributes, which reduces ...
🌐
Python.org
discuss.python.org › python help
Dataclasses and non-dataclasses inheritance - Python Help - Discussions on Python.org
April 19, 2025 - My codebase included (over many modules) code like: class C0: pass @dataclass class DC2: my_field: bool = True class C1(C0, DC2): # original state pass And lo it was good: print(len(C1.__dataclass_fields__)) # 1, life is good But then I tried turning the non-dataclass parent into a dataclass: @dataclass class DC1: pass class C2(DC1, DC2): # messes up __dataclass_fields__ pass print(len(C2.__dataclass_fields__)) # 0 ?? Making the child a dataclass changes the s...
🌐
Reddit
reddit.com › r/python › full support for slots in dataclasses
r/Python on Reddit: Full support for slots in dataclasses
January 30, 2023 -

Many years ago I've made a small library to provide the __slots__ attribute to dataclasses: dataslots. It's stable, well-tested, and supports type checking. Additional features to python implementation:

  • Support for python 3.7 - 3.12 (python 3.10/3.11 added base support for slots).

  • Support for dynamic assignment for new variables (__dict__ in __slots__).

  • Pickling frozen dataclasses (fixed in python 3.10).

  • Support for data descriptors and slots simultaneously.

If you are using older versions of python or need more from dataclasses give it a try.

Github: https://github.com/starhel/dataslots PyPI: https://pypi.org/project/dataslots/

🌐
Real Python
realpython.com › python-data-classes
Data Classes in Python (Guide) – Real Python
March 8, 2024 - Data classes have no explicit syntax for working with slots, but the normal way of creating slots works for data classes as well. (They really are just regular classes!) ... from dataclasses import dataclass @dataclass class SimplePosition: name: str lon: float lat: float @dataclass class SlotPosition: __slots__ = ['name', 'lon', 'lat'] name: str lon: float lat: float
🌐
Python
peps.python.org › pep-0557
PEP 557 – Data Classes | peps.python.org
This PEP describes an addition to the standard library called Data Classes. Although they use a very different mechanism, Data Classes can be thought of as “mutable namedtuples with defaults”. Because Data Classes use normal class definition syntax, y...
🌐
Python
wiki.python.org › moin › UsingSlots
UsingSlots
What Is `__slots__` · The __slots__ declaration allows us to explicitly declare data members, causes Python to reserve space for them in memory, and prevents the creation of __dict__ and __weakref__ attributes. It also prevents the creation of any variables that aren't declared in __slots__
🌐
Python
bugs.python.org › issue46382
Issue 46382: dataclass(slots=True) does not account for slots in base classes - Python tracker
This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/90540
🌐
Medium
medium.com › @2nick2patel2 › dataclasses-that-do-more-42da2989f067
Dataclasses That Do More. Validators, slots, and pattern matching… | by Codastra | Medium
September 21, 2025 - Make Python dataclasses pull real weight: add validations, speed them up with slots=True, and use structural pattern matching for clean orchestration.
🌐
Python.org
discuss.python.org › ideas
Alternative to __slots__ - Ideas - Discussions on Python.org
February 14, 2022 - I would like to have a built-in which creates a slot: class X: a = slot(doc='field a') b = slot(doc='field b') It virtually adds the name to the __slots__ list. No need to pass the field name as argument, it can be set in __set_name__(). The advantage over simple __slots__ is that it can have other options and perform some magic, like control the attribute type or even change the default constructor.
🌐
Trueblade
trueblade.com › blogs › news › python-3-10-new-dataclass-features
Python 3.10: new dataclass features – True Blade Systems Inc
May 10, 2021 - So that's what I did in Python 3.10. In the case where slots=True is specified, and only in that case, @dataclass will create a new class with the computed __slots__ and return that to the caller.
🌐
GitHub
github.com › python › cpython › issues › 90540
dataclass(slots=True) does not account for slots in base classes · Issue #90540 · python/cpython
December 14, 2021 - 3.10only security fixesonly security fixes3.11only security fixesonly security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error · ariebovenbergmannequin · opened · on Jan 14, 2022 · Issue body actions · BPO · 46382 · Nosy · @ericvsmith, @hynek, @serhiy-storchaka, @TeamSpen210, @sobolevn, @AlexWaygood, @ariebovenberg · PRs · bpo-46382 dataclass(slots=True) now takes inherited slots into account #31980 ·
Author   ariebovenberg
🌐
DEV Community
dev.to › sumandari › define-fixed-attributes-dataclass-with-slots-3alo
Define fixed attributes dataclass with __slots__() - DEV Community
June 15, 2023 - >>> @dataclass ... class Circle: ... __slots__ = ("r", ) ... r : int ... >>> c = Circle(10) >>> c Circle(r=10) >>> c.new_attribute = 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Circle' object has no attribute 'new_attribute' ... Backend (Python) developer.