Ben Chuanlong Du's Blog

It is never too late to learn.

Dataclass vs namedtuple in Python

Tips and Traps

  1. Prefer Dataclass to namedtuple for many reasons.

    • A namedtuple is immutable while a dataclass can be both mutable (frozen=False which is the default) or immutable (frozen=True).

      However, namedtuple does have one advantage over dataclass. Members of a namedtuple is assible both via the dot operator and index. In situations where both dot accessing and index accessing of members is required, a namedtuple comes handy. For examples, a list of namedtuple objects can be used as the data for creating a pandas DataFrame but not a list of dataclass objects.

dataclass - mutable

In [1]:
from dataclasses import dataclass


@dataclass
class Person:
    name: str
    age: int = 10
In [2]:
Person("Ben")
Out[2]:
Person(name='Ben', age=10)
In [3]:
p = Person("Ben", 34)
p
Out[3]:
Person(name='Ben', age=34)
In [4]:
str(p)
Out[4]:
"Person(name='Ben', age=34)"

dataclass - immutable

Attributes of the class Person is mutable since frozen=False (default).

In [13]:
p.age = 20
p
Out[13]:
Person(name='Ben', age=20)
In [18]:
@dataclass(frozen=True)
class PersonImmutable:
    name: str
    age: int = 10
In [19]:
PersonImmutable("Ben")
Out[19]:
PersonImmutable(name='Ben', age=10)
In [20]:
p = PersonImmutable("Ben", 30)
p
Out[20]:
PersonImmutable(name='Ben', age=30)

Attribute of PersonImmutable is immutable since frozen=True.

In [22]:
p.age = 20

FrozenInstanceErrorTraceback (most recent call last)
<ipython-input-22-b29e99bf1482> in <module>
----> 1 p.age = 20

<string> in __setattr__(self, name, value)

FrozenInstanceError: cannot assign to field 'age'

namedtuple

In [2]:
from collections import namedtuple
In [7]:
PersonNT = namedtuple("PersonNT", ["name", "age"])
In [8]:
p = PersonNT("Ben Du", 30)
p
Out[8]:
PersonNT(name='Ben Du', age=30)
In [9]:
p[0]
Out[9]:
'Ben Du'
In [10]:
p[1]
Out[10]:
30

Objects of namedtuple as pandas DataFrame Data

In [11]:
import pandas as pd
In [12]:
pd.DataFrame(data=[p])
Out[12]:
name age
0 Ben Du 30
In [ ]:
 

Comments