December 11, 2024

NamedTuple: A pythonic way for writing your code

Spread the love

This article is inspired by an a blog post in RealPython.com, link to that article can be found here. The article on RealPython focuses on namedtuple(), but I will be focusing on NamedTuple. I know it’s a little confusing.

Python’s NamedTuple is used to create other objects that are a subclass of a tuple, the fields within which can be accessed by the dot notation, like obj.attr. By the way, it also supports indexing, so you can access the fields using index. It is available within the typing module. Please note, there is another version of NamedTuple which is namedtuple() within collections. Both generate the same subclasses, but NamedTuple provides some additional functionalities.


Creating a NamedTuple

Let’s quickly look at how to use NamedTuple and then we can discuss a little more about it.

# NamedTuple from typing
from typing import NamedTuple
class Point(NamedTuple):
    x: int
    y: int

point = Point(1, 2)

# namedtuple equivalent
from collections import namedtuple
Point = namedtuple(
    'Point',
    'x y'
)
point = Point(1, 2)

The main difference between the two are:

  • Updated syntax for defining record types
  • Added support for type hints
  • Easy to set default values (more on this later)

Accessing values within a NamedTuple

As mentioned earlier, we can access the values by the dot notation and also by using the index. Let’s quickly look at both the methods.

>>> point.x
1

>>> point[0]
1

Since we are working with a pretty small class the benefit of using the dot notation is not that obvious. But we can see that the dot notation is easier to understand and much more readable that the index.


Setting default values

Let’s now recreate our NamedTuple but with default values.

class Point(NamedTuple):
    x: int = 0
    y: int = 0

point = Point()
print(point)
>>> Point(x=0, y=0)

point = Point(1)
print(point)
>>> Point(x=1, y=0)

Additional Features

Besides the methods inherited from tuple, NamedTuple class also provides three additional methods and three attributes.

Let’s look at the three methods:

# _make method
point._make((2, 4))

>>> Point(x=2, y=4)

# _asdict method
point._asdict()

>>> {'x': 1, 'y': 0}

# _replace method
point._replace(y=8)
>>> Point(x=1, y=8)
  • _make:
    • This method creates NamedTuple instance.
  • _asdict:
    • Converts your NamedTuple to a dictionary. The field names are set to the key and values to values.
  • _replace:
    • This method updates the values of the field name. This may suggest that the method modifies the existing NamedTuple, but that’s not what happens in the back end. This is because NamedTuple instances are immutable.

Let’s now look at the three attributes:

# _field attribute
point._fields

>>> ('x', 'y')

# _field_types
point._field_types

>>> {'x': <class 'int'>, 'y': <class 'int'>}

# _field_defaults
point._field_defaults
>>> {'x': 0, 'y': 0}
  • _fields:
    • Returns a tuple of all the fields.
  • _field_types:
    • Returns a dictionary with field names as key and field types as values.
  • _field_defaults:
    • Returns a dictionary with field names as key and field default values as values.


Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *