[{"data":1,"prerenderedAt":79},["ShallowReactive",2],{"qa-\u002Fpython\u002Foop\u002Fdataclasses-slots":3},{"page":4,"siblings":58,"blog":49},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":49,"seo":50,"seoDescription":51,"stem":52,"subtopic":53,"topic":54,"topicSlug":55,"updated":56,"__hash__":57},"qa\u002Fpython\u002Foop\u002Fdataclasses-slots.md","Dataclasses Slots",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","Python","python",{},true,5,"\u002Fpython\u002Foop\u002Fdataclasses-slots",[23,28,32,37,41,45],{"id":24,"difficulty":25,"q":26,"a":27},"what-dataclass-generates","easy","What does the @dataclass decorator generate for you?","`@dataclass` auto-generates the **boilerplate dunder methods** from the\nclass's annotated fields — primarily **`__init__`**, **`__repr__`**, and\n**`__eq__`**. You declare fields with type hints (and optional defaults) and\nskip writing the constructor by hand.\n\n```python\nfrom dataclasses import dataclass\n\n@dataclass\nclass Point:\n    x: int\n    y: int = 0           # field with a default\n\np = Point(1, 2)\np                        # Point(x=1, y=2)        — generated __repr__\np == Point(1, 2)         # True                   — generated __eq__\n# __init__(self, x, y=0) was generated automatically\n```\n\nYou can opt into more (`order=True` for comparison operators, `frozen=True` for\nimmutability). It removes the repetitive plumbing while leaving normal methods\nup to you.\n",{"id":29,"difficulty":14,"q":30,"a":31},"frozen-dataclass","What does frozen=True do on a dataclass?","`@dataclass(frozen=True)` makes instances **immutable** — assigning to a field\nafter creation raises **`FrozenInstanceError`**. As a bonus, frozen dataclasses\nget a generated **`__hash__`**, so they're usable as **dict keys and set\nmembers**.\n\n```python\nfrom dataclasses import dataclass\n\n@dataclass(frozen=True)\nclass Point:\n    x: int\n    y: int\n\np = Point(1, 2)\np.x = 9            # FrozenInstanceError — immutable\n{p: \"origin\"}      # hashable — works as a dict key\n{Point(1, 2), Point(1, 2)}   # one element — equal and hashable\n```\n\nFrozen dataclasses are the concise, modern way to define **immutable value\nobjects**. Use them whenever an object represents a value that shouldn't change\nafter creation.\n",{"id":33,"difficulty":34,"q":35,"a":36},"default-factory","hard","Why must mutable dataclass defaults use field(default_factory=...)?","A bare mutable default (`tags: list = []`) would be **shared across all\ninstances** — the same default-argument trap as in regular functions — so\ndataclasses **forbid it and raise `ValueError`**. Instead, pass\n**`field(default_factory=list)`**, a zero-arg callable that creates a **fresh\nobject per instance**.\n\n```python\nfrom dataclasses import dataclass, field\n\n@dataclass\nclass Article:\n    title: str\n    tags: list = field(default_factory=list)   # new list each instance\n    # tags: list = []   # would raise ValueError at class-definition time\n\na, b = Article(\"A\"), Article(\"B\")\na.tags.append(\"python\")\nb.tags             # []  — independent, no shared state\n```\n\nUse `default_factory` for any mutable default (`list`, `dict`, `set`) or for a\nvalue that must be computed at construction time. Plain immutable defaults\n(numbers, strings, tuples) are fine inline.\n",{"id":38,"difficulty":34,"q":39,"a":40},"slots","What is __slots__ and what does it buy you?","`__slots__` declares a **fixed set of allowed attributes**, so instances store\nthem in a compact array instead of a per-instance **`__dict__`**. This **saves\nsignificant memory** (no dict per object) and gives **faster attribute access**.\nThe trade-off: you **can't add new attributes** not listed in slots.\n\n```python\nclass Point:\n    __slots__ = (\"x\", \"y\")     # no per-instance __dict__\n    def __init__(self, x, y):\n        self.x, self.y = x, y\n\np = Point(1, 2)\np.x               # 2 — fast access\np.z = 3           # AttributeError — 'z' not in __slots__\n# p.__dict__      # also AttributeError — there is no dict\n\nfrom dataclasses import dataclass\n@dataclass(slots=True)        # dataclasses can generate slots (3.10+)\nclass Fast:\n    x: int\n    y: int\n```\n\nReach for `__slots__` when you create **huge numbers of small objects** and\nmemory matters. For ordinary classes the flexibility of `__dict__` is usually\nworth more than the savings.\n",{"id":42,"difficulty":14,"q":43,"a":44},"dataclass-vs-namedtuple","When would you choose a dataclass over a namedtuple or NamedTuple?","A **`namedtuple`**\u002F**`typing.NamedTuple`** is an **immutable tuple** subclass —\nlightweight, hashable, iterable, and index-accessible, but values can't change.\nA **`@dataclass`** is a regular class — **mutable by default**, supports methods,\ninheritance, and `default_factory`, but isn't a tuple (no unpacking\u002Findexing\nunless you add it).\n\n```python\nfrom typing import NamedTuple\nfrom dataclasses import dataclass\n\nclass PointNT(NamedTuple):     # immutable, tuple-like\n    x: int\n    y: int\nx, y = PointNT(1, 2)           # unpacks like a tuple\n\n@dataclass\nclass PointDC:                 # mutable, full class\n    x: int\n    y: int\n    def shift(self, dx):       # can hold real methods\n        self.x += dx\n\nPointNT(1, 2)[0]   # 1 — index access (tuple)\nPointDC(1, 2).shift(5)         # mutate in place\n```\n\nChoose a **NamedTuple** for small immutable records and tuple semantics; choose a\n**dataclass** when you need mutability, methods, or richer field control. Use\n`frozen=True` dataclasses for immutable value objects that still want class\nfeatures.\n",{"id":46,"difficulty":14,"q":47,"a":48},"post-init","What is __post_init__ used for?","`__post_init__` runs **automatically right after the generated `__init__`** —\nit's the hook for **validation and derived fields** that depend on the\nconstructor arguments. It pairs with `field(init=False)` to declare attributes\nthat aren't constructor parameters but are computed afterward.\n\n```python\nfrom dataclasses import dataclass, field\n\n@dataclass\nclass Rectangle:\n    width: float\n    height: float\n    area: float = field(init=False)     # not a constructor arg\n\n# filled in after __init__:\n    def __post_init__(self):\n        if self.width \u003C= 0 or self.height \u003C= 0:\n            raise ValueError(\"dimensions must be positive\")   # validation\n        self.area = self.width * self.height                  # derived field\n\nr = Rectangle(3, 4)\nr.area            # 12 — computed in __post_init__\nRectangle(-1, 4)  # ValueError\n```\n\nUse `__post_init__` whenever a dataclass needs logic the auto-generated\n`__init__` can't express — validation, normalization, or fields derived from\nothers.\n",null,{"description":11},"Python interview questions on @dataclass — generated methods, frozen=True, field(default_factory=...) for mutable defaults, __slots__ for memory and speed, dataclass vs namedtuple vs NamedTuple, and __post_init__.","python\u002Foop\u002Fdataclasses-slots","Dataclasses & __slots__","Object-Oriented Programming","oop","2026-06-18","rbgsaK-ivBYw25DXEMFBiwSKrF17EhRciQ-ctqZKl34",[59,63,66,70,74,75],{"subtopic":60,"path":61,"order":62},"Inheritance & the MRO","\u002Fpython\u002Foop\u002Finheritance",1,{"subtopic":64,"path":65,"order":12},"Classes, Instances & __init__","\u002Fpython\u002Foop\u002Fclasses",{"subtopic":67,"path":68,"order":69},"Dunder \u002F Magic Methods","\u002Fpython\u002Foop\u002Fdunder-methods",3,{"subtopic":71,"path":72,"order":73},"Methods & Properties","\u002Fpython\u002Foop\u002Fmethods-properties",4,{"subtopic":53,"path":21,"order":20},{"subtopic":76,"path":77,"order":78},"Abstract Base Classes & Protocols","\u002Fpython\u002Foop\u002Fabc-protocols",6,1781808680292]