Skip to content

Instantly share code, notes, and snippets.

@elnikkis
Created July 15, 2020 08:52
Show Gist options
  • Save elnikkis/744a636c1187d2d016d23465007281a4 to your computer and use it in GitHub Desktop.
Save elnikkis/744a636c1187d2d016d23465007281a4 to your computer and use it in GitHub Desktop.
Typed namedtuple
# -*- coding: utf-8 -*-
from collections import namedtuple
def typednamedtuple(typename, field_names, field_types):
'''Typed namedtuple
An implementation of typed namedtuple.
>>> Point = typednamedtuple('Point', ['id', 'x', 'y'], [str, float, float])
>>> Point.__doc__
'Point(id: str, x: float, y: float)'
>>> p = Point('nodeXX', '0.8', '0.5')
>>> p.id
'nodeXX'
>>> p.x + p.y
1.3
'''
ntuple = namedtuple(typename, field_names)
_tuple_new = ntuple.__new__
def __new__(cls, *args):
converted_args = [t(f) for f, t in zip(args, field_types)]
return _tuple_new(cls, *converted_args)
ntuple.__new__ = __new__
arg_list = ', '.join(f'{f}: {t.__name__}' for f, t in zip(field_names, field_types))
ntuple.__doc__ = f'{typename}({arg_list})'
return ntuple
if __name__ == '__main__':
inputs = ['user01', '0.2', '0.4']
fields = ['user_id', 'x', 'y']
types = [str, float, float]
Point = typednamedtuple('Point', fields, types)
p = Point(*inputs)
print(p)
print(p.x + p.y)
Point2 = namedtuple('Point2', fields)
converted_inputs = [t(i) for i, t in zip(inputs, types)]
p = Point2(*converted_inputs)
print(p)
print(p.x + p.y)
from typing import NamedTuple
class Point3(NamedTuple):
user_id: str
x: float
y: float
p = Point3(*inputs)
print(p)
print(p.x + p.y)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment