Do you hate writing monotonous
__init__, __repr__ and __eq__ for each class? Dataclasses do it for you.😩 Manual implementation is a boring and stupid task
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
def __eq__(self, other):
return self.x == other.x and self.y == other.y
class User:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"User(name={self.name}, age={self.age})"
def __eq__(self, other):
return self.name == other.name and self.age == other.age
Problem:
This is crap. Tons of boilerplate code that's easy to break or forget to update.
✔️ Correctly (via @dataclass)
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
@dataclass
class User:
name: str
age: int
p1 = Point(10, 20)
p2 = Point(10, 20)
u = User("Ivan", 30)
print(p1) # Point(x=10, y=20)
print(p1 == p2) # True
print(u) # User(name='Ivan', age=30)
How it works:
The decorator @dataclass automatically generates methods based on type annotations.
Customizing a dataclass:
from dataclasses import dataclass, fieldinits generated by default?:
@dataclass(order=True, frozen=True)
class Product:
name: str
price: float = 0.0
tags: list[str] = field(default_factory=list, compare=False)
def expensive(self):
return self.price > 1000
p1 = Product("Laptop", 1500.0)
p2 = Product("Mouse", 50.0)
print(p1 > p2) # True (price comparison due to order=True)
p1.tags.append("tech")
# p1.name = "PC" # Error! frozen=True makes the object immutable
🔵 __initreprtializer with parametersare not a replacement for regular classes. Use them for data structures where standard methods are needed.
🔵 __repr_eqetty string representation
🔵 __eq__ - comparison acltllles
gth geTrue: __lt__, __le__, __gt__, __ge__
Important:
Dataclasses
👩💻 @DataScience4
