@Data#
The all-in-one decorator: one line gives a class a constructor, __repr__,
__eq__, __hash__, and a getter/setter per field.
The problem it solves#
A class that just holds a few fields still needs a constructor, a readable
repr, value-based equality and hashing, and (Lombok-style) accessors.
Writing those by hand is repetitive and drifts out of sync whenever a field
is added or renamed. @Data derives all of them from the class’s
annotations, so there is nothing to keep in sync.
Usage#
from inito import Data
@Data
class User:
name: str
email: str
age: int = 0
user = User("Ada", "[email protected]", age=30)
print(user) # User(name='Ada', email='[email protected]', age=30)
print(user == User("Ada", "[email protected]", 30)) # True
print(user.get_name()) # Ada
user.set_age(31)
What it generates#
Member |
Behaviour |
|---|---|
|
required fields first, then defaulted ones — the usual Python ordering |
|
|
|
value equality; different classes compare |
|
hashes the tuple of all field values |
|
one per field (unless |
|
one per field (unless |
Fields are the class’s annotated attributes, accumulated across the MRO
(base-class fields first). ClassVar-annotated attributes are ignored.
Options#
@Data can be used bare (@Data) or configured (@Data(...)):
Option |
Default |
Effect |
|---|---|---|
|
|
make instances immutable (assignment/deletion raise |
|
|
set |
|
|
set |
@Data(frozen=True) # immutable value object, no setters
@Data(include_setters=False) # read-only accessors, but still mutable via obj.x = ...
@Data(include_getters=False) # no getters
frozen=True and @Value both give a genuinely immutable class; @Value
is the more descriptive choice when immutability is the point (see
@Value).
Notes & gotchas#
Mutable defaults (a
list/dict/set) needdataclasses.field, which inito reads only from a real dataclass — stack@dataclass:from dataclasses import dataclass, field @Data @dataclass class Config: tags: list = field(default_factory=list) # a fresh list per instance
Your own methods are untouched.
@Dataonly attaches the members listed above; any other method you define is left alone. It will overwrite a method it generates (e.g. a hand-written__repr__) since it attaches its version last.include_setters=Falseis not immutability — it only omits theset_xhelpers;obj.x = 5still works. Usefrozen=True(or@Value) to actually forbid mutation.
See also#
@Value —
@Datawithout setters, always immutable.Accessors, @ToString, @EqualsAndHashCode — the atomic pieces
@Databundles.