| 5 | import sys |
| 6 | |
| 7 | def named_tuple(classname, fieldnames): |
| 8 | # Populate a dictionary of field property accessors |
| 9 | cls_dict = { name: property(operator.itemgetter(n)) |
| 10 | for n, name in enumerate(fieldnames) } |
| 11 | |
| 12 | # Make a __new__ function and add to the class dict |
| 13 | def __new__(cls, *args): |
| 14 | if len(args) != len(fieldnames): |
| 15 | raise TypeError('Expected {} arguments'.format(len(fieldnames))) |
| 16 | return tuple.__new__(cls, (args)) |
| 17 | |
| 18 | cls_dict['__new__'] = __new__ |
| 19 | |
| 20 | # Make the class |
| 21 | cls = types.new_class(classname, (tuple,), {}, |
| 22 | lambda ns: ns.update(cls_dict)) |
| 23 | cls.__module__ = sys._getframe(1).f_globals['__name__'] |
| 24 | return cls |
| 25 | |
| 26 | if __name__ == '__main__': |
| 27 | Point = named_tuple('Point', ['x', 'y']) |