[Tutor] subclassing list -- slicing doesn't preserve type

Brian van den Broek bvande at po-box.mcgill.ca
Tue Feb 22 20:26:32 CET 2005


Karl Pflästerer said unto the world upon 2005-02-22 07:53:
> On 22 Feb 2005, bvande at po-box.mcgill.ca 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

<SNIP my examples of behaviour: notably, slicing doesn't preserve 
my_list type>

>>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.

<SNIP Karl's similar output, but with desired behaviour ;-) >


> You must also think about the other methods which return a newly
> allocated object.
> 
> 
>    Karl

Thanks Karl (and Kent in another response),

use of super is new to me; from a quick glance at the docs, I am glad 
to have been pointed at it. For the quick and dirty, I think I will go 
the __getslice__ way, deprecation be damned. But, learning how to do 
it the way you have above is high on the list of things to do.

Thanks and best,

Brian vdB



More information about the Tutor mailing list