Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteImport dataclass from dataclasses, place @dataclass directly above a class, and list each field as an annotated class attribute. Python then generates the boilerplate you would otherwise write by hand: an __init__ method, a readable __repr__, and an __eq__ method. The remaining decisions concern defaults, which methods to generate, and whether instances may change after creation.
What the decorator generates
The decorator reads the annotated class variables in the class body and treats each one as a field. It then adds special methods based on those fields. It does not wrap the class or return a replacement; the class you decorated is the class you get back.
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
point = Point(2.0, 3.5)
print(point) # Point(x=2.0, y=3.5)
print(point == Point(2.0, 3.5)) # True
With no arguments, @dataclass generates __init__, __repr__, and __eq__. Generated equality only returns true when both objects have the identical type, so a Point never equals a subclass instance with the same values.
Equality changed in Python 3.13. Earlier versions compared tuples of field values; Python 3.13 compares fields individually. For most code the results match, but edge cases such as values that behave unusually under equality (NaN is the classic example) can differ. If your code depends on that behavior, pin the target version and test on it. The official reference is the Python 3.13 dataclasses documentation.
#1 Best Overall
Annotations are not runtime type checks. A field declared x: float will still accept a string if a caller passes one. Two special annotations change how a class variable is treated. ClassVar marks shared class-level data that is not a field. InitVar marks a value that is passed to __init__ and forwarded to __post_init__() but not stored as an attribute.
Declaring fields and defaults
Simple defaults
Assign a default in the class body for immutable values such as numbers, strings, tuples, and None:
@dataclass
class Server:
host: str
port: int = 8080
debug: bool = False
Fields with defaults can be omitted when calling the class: Server("localhost") sets port to 8080.
Per-instance defaults with default_factory
Do not use a mutable object such as a list or dictionary as a plain default. Every instance would share the same object. Use field(default_factory=...) so each instance receives a newly created value:
Rank #2
from dataclasses import dataclass, field
@dataclass
class Inventory:
name: str
items: list[str] = field(default_factory=list)
a = Inventory("front")
b = Inventory("back")
a.items.append("tape")
print(b.items) # []
Controlling individual fields with field()
field() accepts options that change how one field behaves:
init=Falsekeeps the field out of the generated__init__. Use it for values computed in__post_init__().repr=Falsehides the field from the generated__repr__, which helps with secrets or large data.compare=Falseexcludes the field from generated equality and ordering comparisons.hash=controls whether the field takes part in the generated__hash__.metadatastores a mapping that third-party tools can read.kw_only=Truemakes the field keyword-only.
Ordering of required and default fields
A field without a default cannot come after a field with a default in the generated initializer. This rule also applies to fields inherited from a dataclass base class. Breaking it raises a TypeError when the class is defined:
@dataclass
class Bad:
x: int = 0
y: int # TypeError: non-default argument 'y' follows default argument
Reorder the fields, or make the earlier field keyword-only.
Keyword-only fields
To force callers to pass a field by name, mark it with field(kw_only=True), or insert a KW_ONLY sentinel so that every later field is keyword-only:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
from dataclasses import dataclass, KW_ONLY
@dataclass
class Request:
url: str
_: KW_ONLY
timeout: float = 5.0
retries: int = 3
Request("https://example.com", timeout=2.0)
Keyword-only fields are not included in __match_args__, so they cannot be matched by position in a match statement.
Decorator options
The decorator accepts keyword arguments that switch individual methods on or off. The table lists the defaults and the Python version notes stated in the Python 3.13 reference.
| Option | Default | Effect | Version note |
|---|---|---|---|
init |
True |
Generates __init__ unless the class already defines one. |
Not stated in the Python 3.13 reference |
repr |
True |
Generates a readable __repr__ unless one already exists. |
Not stated in the Python 3.13 reference |
eq |
True |
Generates __eq__ comparing fields; requires identical instance types. |
Comparison method changed in Python 3.13 |
order |
False |
Generates the four ordering methods. Requires eq=True. |
Not stated in the Python 3.13 reference |
frozen |
False |
Raises FrozenInstanceError on assignment or deletion of fields. |
Not stated in the Python 3.13 reference |
unsafe_hash |
False |
Forces generation of __hash__. By default hashing follows the eq and frozen combination. |
Not stated in the Python 3.13 reference |
match_args |
True |
Generates __match_args__ from positional, non-keyword-only initializer parameters. |
Not stated in the Python 3.13 reference |
kw_only |
False |
Makes every field keyword-only. | Added in Python 3.10 |
slots |
False |
Generates __slots__ for the class. |
Added in Python 3.10 |
weakref_slot |
False |
Adds a slot that allows weak references. Requires slots=True. |
Added in Python 3.11 |
frozen=True
@dataclass(frozen=True)
class Config:
host: str
port: int = 8080
c = Config("localhost")
c.port = 9000 # raises FrozenInstanceError
A frozen dataclass prevents ordinary attribute assignment, but it is not truly immutable. The generated initializer must set fields through object.__setattr__, which adds a small performance cost during construction. Code can also call object.__setattr__ directly to change a field, so treat frozen=True as a guard against accidental mutation rather than a security boundary.
When eq=True and frozen=True are both set, the class gets a generated __hash__, so its instances can be used in sets and as dictionary keys. Frozen instances are the usual choice for value objects.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesorder=True
@dataclass(order=True)
class Version:
major: int
minor: int
print(Version(1, 4) < Version(2, 0)) # True
Ordering compares the fields in declaration order, as tuples. Use it only when that sequence is a meaningful sort key. A field such as a free-text note should be excluded with field(compare=False).
slots=True
@dataclass(slots=True)
class Sample:
value: int
s = Sample(3)
s.extra = 1 # AttributeError: no __dict__ on slotted instances
Slotted instances store fields in fixed slots rather than a per-instance __dict__. This reduces memory use and blocks accidental new attributes. It also means the class cannot be given attributes it did not declare. Add weakref_slot=True only when you need weakref.ref() to work on instances, and remember that it requires Python 3.11 or later.
Helper functions
fields() and the shape of a field
fields(obj_or_class) returns a tuple of field descriptors, each with name, type, and default attributes. ClassVar and InitVar pseudo-fields are excluded. The result is useful for generic code such as serializers:
from dataclasses import fields
[f.name for f in fields(point)] # ['x', 'y']
asdict() and astuple()
asdict() converts an instance into a dictionary, and astuple() converts it into a tuple. Both recurse into nested dataclasses, lists, tuples, and dictionaries. Other values are deep-copied, so the result does not share mutable objects with the original.
Best Value
from dataclasses import asdict, astuple
asdict(point) # {'x': 2.0, 'y': 3.5}
astuple(point) # (2.0, 3.5)
If you only need a shallow dictionary of top-level fields, build it from fields() and getattr():
{f.name: getattr(point, f.name) for f in fields(point)}
replace()
replace() creates a new instance with some fields changed. It calls the class initializer, so __post_init__() runs again. Fields declared with init=False cannot be passed as changes, and doing so raises an error.
from dataclasses import replace
moved = replace(point, x=5.0) # Point(x=5.0, y=3.5)
This is the usual way to “update” a frozen dataclass, because the original instance cannot be modified.
Quick Recap
Choosing options
- Plain data holder with mutable state: use the default settings and add
default_factoryfor mutable defaults. - Value object that should not change: use
frozen=True, and update it withreplace(). - Objects that must be sorted: add
order=Trueonly after confirming that field order is the intended sort key, and exclude fields that should not affect comparison. - Many instances or call sites where argument order is error-prone: use
kw_only=Trueon the class or individual fields. Remember that this requires Python 3.10 or later. - Memory-sensitive code that does not need dynamic attributes: use
slots=True, and check that no code relies on__dict__. - Code that must run on older interpreters: check the version column above before using
kw_only,slots, orweakref_slot, and avoid depending on equality internals if you support both Python 3.12 and 3.13.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →




