== Ordered lists with named fields for Python I periodically find myself dealing with [[structures EmulatingStructsInPython]] that are basically ordered lists with named fields, where elements 0, 1, and 2 are naturally named 'a', 'b', and 'c' and sometimes you want to refer to them by name instead of having to remember their position. This pattern even crops up in the standard Python library, often with functions that started out just returning an ordered list and grew the named fields portion later as people discovered how annoying it was to have to remember that the hour was [[field 3 http://www.python.org/doc/current/lib/module-time.html]]. This being Python, I've built myself some general code to add named fields on top of sequence types like _list_ or _tuple_. For maximum generality my code supports using field names both as attribute names and as indexes, so you can use both _obj.field_ and _obj["field"]_, and you can even do crazy things like _obj["field":-1]_. The code: class GetMixin(object): fields = {} def _mapslice(self, key): s, e, step = key.start, key.stop, key.step if s in self.fields: s = self.fields[s] if e in self.fields: e = self.fields[e] return slice(s, e, step) def _mapkey(self, key): if isinstance(key, tuple): pass elif isinstance(key, slice): key = self._mapslice(key) elif key in self.fields: key = self.fields[key] return key def __getitem__(self, key): key = self._mapkey(key) return super(GetMixin, self).__getitem__(key) def __getattr__(self, name): if name in self.fields: return self[self.fields[name]] raise AttributeError, \ "object has no attribute '%s'" % name class SetMixin(GetMixin): def __setitem__(self, key, value): key = self._mapkey(key) super(SetMixin, self).__setitem__(key, value) def __setattr__(self, name, value): if name in self.fields: o = self.fields[name] self[o] = value else: self.__dict__[name] = value class Example(SetMixin, list): fields = {'a': 0, 'b': 1, 'c': 2} The _fields_ class variable is a dictionary mapping the names of the fields to their index offsets; it need not include all fields, and not all named fields necessarily have values for a particular list (since nothing checks the list length). GetMixin just lets you read the named fields and can be mixed in with tuples; SetMixin lets you write to them by name too, and so needs to be mixed in with lists or other writable sequence types. The easiest way to generate the _fields_ value for the usual case of sequential field names starting from the first element of the list is to use a variant of the _enumerate_ function from the [[itertools recipes http://www.python.org/doc/current/lib/itertools-recipes.html]]: > from itertools import * > def enum_args(*args): > return izip(args, count()) > > class Example(SetMixin, list): > fields = dict(enum_args('a', 'b', 'c')) (If you're going to do this a lot, make a version of ((enum_args)) that does the _dict()_ step too.) Inheriting from list, tuple, etc does have one practical wart: you probably want to avoid using field names that are the names of methods that you want to use, because you won't be able to use the _obj.field_ syntax for accessing them. Amusingly, you will be able to *set* them using that syntax, because __setattr__ gets called for everything, existing attributes included (which is why it needs the dance at the end with the instance's __dict__). (This code is not quite neurotically complete; truly neurotically complete code would make the available fields appear in _dir()_'s output. But I don't want to try to think what sort of hacks that would take, since I am seeing visions of dancing metaclasses that automatically create properties for each field name.)