On 22 Feb 2005, [EMAIL PROTECTED] wrote: > I'm trying to figure out how to subclass the list built-in. > > .>>> class my_list(list): > def __init__(self, sequence=None): > list.__init__(self, sequence) > self.spam = 1 > > .>>> mine = my_list((1,2,3,4)) > .>>> mine.append(42) > .>>> mine > [1, 2, 3, 4, 42] > .>>> type(mine) > <class '__main__.my_list'> > .>>> damn = mine[1:3] > .>>> type(damn) > <type 'list'> > .>>> damn > [2, 3] > .>>> > > I had thought that by subsclassing list I got all list-like properties > for free. Append (among others) are available for my_list instances. > But slicing returns a list, rather than a my_list. I can see that this > is list-like in it's way, but I'd rather have be so in mine ;-) > > I've read in the docs that UserList is discouraged, and in the > Nutshell that the __getslice__, etc. special methods are depreciated.
But the problem is here: list() defines a __getslice__ method. > So, how can I get slicing to preserve the my_list type? And why does > the above class get so much for free, but not slicing? It gets also slicing for free but think about what happens when you call e.g. `append'; you *mutate an existing object in place* (i.e. a destructive operation). So you change the already existing object which is an instance of Mylist. On the other hand with slicing you get a *new* object back; you never told Python that you also wanted that new object to be of type Mylist. You could do it e.g. like that: class Mylist (list): def __init__(self, seq=None): super(self.__class__, self).__init__(seq) def __getslice__(self, start, stop): return self.__class__(super(self.__class__, self).__getslice__(start, stop)) def __getitem__(self, key): if isinstance(key, slice): return self.__class__(super(self.__class__, self).__getitem__(key)) else: return super(self.__class__, self).__getitem__(key) For simple slices Python calls `list.__getslice__' for extended slices list.__getitem__ gets called. So the above handles all cases. . >>> L = Mylist((1,2,3,4)) . >>> L[1] . 2 . >>> L[1:2] . [2] . >>> type(_) . <class '__main__.Mylist'> . >>> L[0:4:2] . [1, 3] . >>> type(_) . <class '__main__.Mylist'> . >>> You must also think about the other methods which return a newly allocated object. Karl -- Please do *not* send copies of replies to me. I read the list _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor