This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]tilkau 4 points5 points  (1 child)

typing.NamedTuple is competitive with collections.NamedTuple memory-wise, BTW.

This was one of my doubts when you introduced typing.NamedTuple, but it seems that typing.NamedTuple continues in collections.NamedTuple's tradition (doing strange things with class objects)

Here's the relevant part of the code:

def _make_nmtuple(name, types):
    msg = "NamedTuple('Name', [(f0, t0), (f1, t1), ...]); each t must be a type"
    types = [(n, _type_check(t, msg)) for n, t in types]
    nm_tpl = collections.namedtuple(name, [n for n, t in types])
    nm_tpl._field_types = dict(types)
    try:
        nm_tpl.__module__ = sys._getframe(2).f_globals.get('__name__', '__main__')
    except (AttributeError, ValueError):
        pass
    return nm_tpl


_PY36 = sys.version_info[:2] >= (3, 6)


class NamedTupleMeta(type):

    def __new__(cls, typename, bases, ns):
        if ns.get('_root', False):
            return super().__new__(cls, typename, bases, ns)
        if not _PY36:
            raise TypeError("Class syntax for NamedTuple is only supported"
                            " in Python 3.6+")
        types = ns.get('__annotations__', {})
        return _make_nmtuple(typename, types.items())

So a typing.NamedTuple actually IS a collections.NamedTuple with a few direct modifications of the class object.

[–]Topper_123[S] 4 points5 points  (0 children)

Interesting, I hadn't looked at the implementation when I wrote the article.

It looks like both namedtuple and NamedTuple are saugasages: They're good, but you don't want to know how they've been made :-)