Let's talk about dataclasses in Python.

This `Point`

class represents a 2-dimensional point:

```
class Point:
"""A two-dimensional point."""
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
```

This class accepts arguments (thanks to the initializer method):

```
>>> from point import Point
>>> p = Point(1, 2)
```

And it has a friendly string representation (thanks to the `__repr__`

method):

```
>>> p
Point(x=1, y=2)
```

Instead of writing our `__init__`

and `__repr__`

method ourselves, we could use the `dataclass`

decorator (from Python's dataclasses module) when defining our class.

The `dataclass`

decorator requires us to define the attributes (and arguments) of our class with type hints:

```
from dataclasses import dataclass
@dataclass
class Point:
"""A two-dimensional point."""
x: float
y: float
```

The resulting class is essentially equivalent to this:

```
class Point:
"""A two-dimensional point."""
def __init__(self, x: float, y: float) -> None:
self.x = x
self.y = y
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
def __eq__(self, other):
"""Return True if our point is equal to the other point."""
if not isinstance(other, Point):
return NotImplemented
return (self.x, self.y) == (other.x, other.y)
```

It has an initializer and a nice string representation (just as before):

```
>>> from point import Point
>>> p = Point(1, 2)
>>> p
>>> Point(x=1, y=2)
```

We can access `x`

and `y`

attributes (just as in our previous class):

```
>>> p.x
1
>>> p.y
2
```

But we can also check equality between two `Point`

objects:

```
>>> p == Point(1, 2)
True
```

We get all of that for free thanks to the `dataclass`

decorator.

To make our `Point`

objects immutable, we could pass `frozen=True`

to our `dataclass`

decorator:

```
from dataclasses import dataclass
@dataclass(frozen=True)
class Point:
"""A two-dimensional point."""
x: float
y: float
```

Now our `Point`

objects are immutable which means we can't assign to their attributes:

```
>>> p = Point(1, 2)
>>> p.x = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 4, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'x'
```

Whenever you'd like to quickly create a class with a friendly interface (with a nice string representation and sensible equality checking), consider reaching for the `dataclass`

decorator from Python's dataclasses module.

Need to **fill-in gaps** in your Python skills?

Sign up for my Python newsletter where **I share one of my favorite Python tips every week**.

✕

↑

A Python Tip Every Week

Need to **fill-in gaps** in your **Python skills**? I send weekly emails designed to do just that.