Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How named tuples are implemented internally in python?

Named tuples are easy to create, lightweight object types. namedtuple instances can be referenced using object-like variable deferencing or the standard tuple syntax. If these data structures can be accessed both by object deferencing & indexes, how are they implemented internally? Is it via hash tables?

like image 204
Vivek S Avatar asked Jul 29 '13 05:07

Vivek S


People also ask

How are named tuples implemented in Python?

To create a named tuple, import the namedtuple class from the collections module. The constructor takes the name of the named tuple (which is what type() will report), and a string containing the fields names, separated by whitespace. It returns a new namedtuple class for the specified fields.

How tuple works internally in Python?

Python has two similar sequence types such as tuples and lists. The most well-known difference between them is that tuples are immutable, that is, you cannot change their size as well as their immutable objects. Internally, both lists and tuples are implemented as a list of pointers to the Python objects (items).

What are named tuples?

A named tuple is an extension and custom data type that enrich built-in tuples with extra utilities. They are very useful in context where we need to create a data structure that can be accessed by both the positional index and the named attribute of the elements.


1 Answers

Actually, it's very easy to find out how a given namedtuple is implemented: if you pass the keyword argument verbose=True when creating it, its class definition is printed:

>>> Point = namedtuple('Point', "x y", verbose=True)
from builtins import property as _property, tuple as _tuple
from operator import itemgetter as _itemgetter
from collections import OrderedDict

class Point(tuple):
    'Point(x, y)'

    __slots__ = ()

    _fields = ('x', 'y')

    def __new__(_cls, x, y):
        'Create new instance of Point(x, y)'
        return _tuple.__new__(_cls, (x, y))

    @classmethod
    def _make(cls, iterable, new=tuple.__new__, len=len):
        'Make a new Point object from a sequence or iterable'
        result = new(cls, iterable)
        if len(result) != 2:
            raise TypeError('Expected 2 arguments, got %d' % len(result))
        return result

    def _replace(_self, **kwds):
        'Return a new Point object replacing specified fields with new values'
        result = _self._make(map(kwds.pop, ('x', 'y'), _self))
        if kwds:
            raise ValueError('Got unexpected field names: %r' % list(kwds))
        return result

    def __repr__(self):
        'Return a nicely formatted representation string'
        return self.__class__.__name__ + '(x=%r, y=%r)' % self

    @property
    def __dict__(self):
        'A new OrderedDict mapping field names to their values'
        return OrderedDict(zip(self._fields, self))

    def _asdict(self):
        '''Return a new OrderedDict which maps field names to their values.
           This method is obsolete.  Use vars(nt) or nt.__dict__ instead.
        '''
        return self.__dict__

    def __getnewargs__(self):
        'Return self as a plain tuple.  Used by copy and pickle.'
        return tuple(self)

    def __getstate__(self):
        'Exclude the OrderedDict from pickling'
        return None

    x = _property(_itemgetter(0), doc='Alias for field number 0')

    y = _property(_itemgetter(1), doc='Alias for field number 1')

So, it's a subclass of tuple with some extra methods to give it the required behaviour, a _fields class-level constant containing the field names, and property methods for attribute access to the tuple's members.

As for the code behind actually building this class definition, that's deep magic.

like image 64
Zero Piraeus Avatar answered Oct 13 '22 03:10

Zero Piraeus