Less Boilerplate With @dataclass
Writing __init__, __repr__, and __eq__ by hand for a simple data-holding class gets repetitive. The @dataclass decorator from the standard library writes them for you. You just list the fields with type hints.
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
p = Point(1, 2)
print(p) # Point(x=1, y=2) (free __repr__)
print(p == Point(1, 2)) # True (free __eq__)
print(p.x, p.y) # 1 2With three lines you got an __init__ that takes x and y, a readable __repr__, and value-based __eq__. No self.x = x chores.
Defaults and methods
Fields can have defaults, and you can still add your own methods like any class:
from dataclasses import dataclass
@dataclass
class Item:
name: str
price: float
qty: int = 1
def total(self):
return self.price * self.qty
i = Item("Pen", 2.5, 4)
print(i.total()) # 10.0One caution on defaults: a mutable default such as tags: list = [] is not allowed and raises ValueError: mutable default ... is not allowed. It is the same shared-default trap functions have, so dataclasses block it up front. Reach for field(default_factory=list) instead, which hands every instance its own fresh list.
from dataclasses import dataclass, field
@dataclass
class Cart:
items: list = field(default_factory=list)
print(Cart().items) # []The type hints (x: int) are not enforced by Python, they just document intent. The real work is the boilerplate the decorator generates.
Use @dataclass to define a class Product with fields name (str), price (float), and quantity (int) defaulting to 1. Add a method subtotal(self) returning price * quantity. Remember to import dataclass from dataclasses.
This lesson is locked
Lessons open one at a time. Finish the previous lesson to unlock this one.