On Mar 31, 7:49 am, "Frank Millman" <fr...@chagford.com> wrote: > Hi all > > I needed something similar to, but not quite the same as, > collections.namedtuple. > > The differences are that namedtuple requires the 'names' to be provided at > creation time, and then lends itself to creating multiple instances of > itself. I wanted a more generic class where I could supply the 'names' and > 'values' at instantiation time. > > I came up with a simple solution that seems to work - > > >>> class MyTuple(tuple): > > ... def __new__(cls, names, values): > ... for name, value in zip(names, values): > ... setattr(cls, name, value) > ... return tuple.__new__(cls, values) > ... > > >>> names = ['A', 'B', 'C'] > >>> values = ['a', 'b', 'c'] > > >>> tup = MyTuple(names, values) > > >>> print tup > ('a', 'b', 'c') > > >>> print tup[0] > a > > >>> print tup.B > b > > Then I had a need to add elements after the tuple had been created. As > tuples are immutable, I thought it would be easy to change it to a list. > However, it does not work - > > >>> class MyList(list): > > ... def __new__(cls, names, values): > ... for name, value in zip(names, values): > ... setattr(cls, name, value) > ... return list.__new__(cls, values) > ...>>> names = ['A', 'B', 'C'] > >>> values = ['a', 'b', 'c'] > > >>> lst = MyList(names, values) > > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: list() takes at most 1 argument (2 given) > > > > I can find a workaround, but I would be interested to know the reason why it > does not work. > > Version is 2.6.2. > > Thanks > > Frank Millman
When subclassing immutable types, you need to override __new__; otherwise you need to override __init__. Here is an in-depth explanation: http://www.python.org/download/releases/2.2/descrintro/#metaclasses Here is some code: class MyTuple(tuple): def __new__(cls, names, values): for name, value in zip(names, values): setattr(cls, name, value) return tuple.__new__(cls, values) class MyList(list): def __init__(self, names, values): list.__init__(self, values) for name, value in zip(names, values): setattr(self, name, value) names = ['A', 'B', 'C'] values = ['a', 'b', 'c'] tup = MyTuple(names, values) print tup print tup[0] print tup.B lst = MyList(names, values) print lst print lst[0] print lst.B L. -- http://mail.python.org/mailman/listinfo/python-list