
I've been experimenting with this: class QuickNamedTuple(tuple): def __new__(cls, **kwargs): inst = super().__new__(cls, tuple(kwargs.values())) inst._names = tuple(kwargs.keys()) return inst def __getattr__(self, attr): if attr in self._names: return self[self._names.index(attr)] raise AttributeError(attr) def __repr__(self): values = [] for i, name in enumerate(self._names): values.append(f'{name}={self[i]}') return f'({", ".join(values)})' It's a quick scrap and probably not ideal code, but the idea is the point. I believe this is how the new "quick" named tuple should ideally work: In: ntuple = QuickNamedTuple(x=1, y=2, z=-1) In: ntuple Out: (x=1, y=2, z=-1) In: ntuple[1] == ntuple.y Out: True In: ntuple == (1, 2, 3) Out: True In: ntuple == QuickNamedTuple(z=-1, y=2, x=1) Out: False So yeah, the order of the keyword arguments would matter in my case, and I've found it to work the best. How often do you get the keywords in a random order? And for those cases, you have SimpleNameSpace, or you can just use the old namedtuple. But most of the time you always have the same attributes in the same order (think of reading a CSV for example), and this would be just a normal tuple, but with custom names for the indexes. Just my two cents and thoughts from an everyday Python developer.