For more on classes, refer Object Oriented Python.
A Python dataclass lets you define classes that are only used to store data. It saves you some boilerplate; by writing @dataclass you can generate __init__(), __repr__() and __eq__() automatically.
Introduction
from dataclasses import dataclass
@dataclass
class Book:
pages: int
author: str
demo = book('100', 'Pippa Python')
print(demo.pages)
print(demo.author)This class comes with basic functionality already implemented. A minimal regular class would’ve looked like this:
class Book:
def __init__(self, pages: int, author: str):
self.pages = pages
self.author = authorBy default dataclasses also provide a repr method for string representation.
That is equivalent to:
class Book:
def __init__(self, pages: int, author: str):
self.pages = pages
self.author = author
def __repr__(self):
return (f'{self.__class__.__name__}'
f'(pages={self.pages!r}), (author={self.author!r})'
)
def __eq__(self, other):
if other.__class__ is not self.__class__:
return NotImplemented
return (self.pages, self.author) == (other.pages, other.author)Well, that was a lot of boilerplate!
Features
You can add default values, type hints, etc. You can also add methods.
from dataclasses import dataclass
@dataclass
class Position:
name: str
longitude: float = 0.0
latitude: float = 0.0
nearest: list[float] = []
def distance(self, other) -> float:
pass # use trigonometry or somethingYou can also override the __repr__ or __str__ methods to represent the data class however you want.
You can also subclass dataclasses via inheritance. But keep in mind that if a parameter has a default value, all following parameters must also have a default value. As an example:
@dataclass
class Capital(Position):
country: str
# this is going to crash with "non default arugument 'country' follows default argument"because this tries to create a constructor like:
def __init__(name: str, longitude: float = 0.0, latitude: float = 0.0, nearest: list[float] = [], country: str):
passSo the correct version is:
@dataclass
class Capital(Position):
country: str = 'Polygondwanaland'Forms for the decorator
The @dataclass decorator has two forms - one without any parantheses or parameters, and one with those. The following parameters are supported:
init: Add__init__()method? Default isTrue.repr: Add__repr__()method? Default isTrue.eq: Add__eq__()method? Default isTrue.order: Add ordering methods? Default isFalse.unsafe_hash: Force the addition of a__hash__()method? Default isFalse.frozen: IfTrue, assigning to fields raises an exception. Default isFalse.
The order thing just makes comparison easier - and sorting too.
ex.
from dataclasses import dataclass
@dataclass(order=True)
class Book:
name: str
pages: int
book1 = Book('Short', 100)
book2 = Book('Long', 800)
print(book2 > book1)
# TrueOptimisations
Slots can be used to make classes faster and use less memory. Data classes have explicit syntax for working with slots, but the normal way of creating slots works with dataclasses as well (i.e. using __slots__).
from dataclasses import dataclass
@dataclass
class SimpleBook:
name: str
author: str
@dataclass
class SlotBook:
__slots__ = ['name', 'author']
name: str
author: strSlot classes can be faster to work with. You can easily have any dataclass have slots by providing the slots=True argument.
from dataclasses import dataclass
@dataclass(slots=True)
class Book:
name: str
author: str