Subclassing list, what special methods do this?

Matimus mccredie at gmail.com
Fri Jun 13 20:43:15 EDT 2008


On Jun 13, 11:38 am, Mike Kent <mrmak... at cox.net> wrote:
> For Python 2.5 and new-style classes, what special method is called
> for mylist[2:4] = seq and for del mylist[2:4] (given that mylist is a
> list, and seq is some sequence)?
>
> I'm trying to subclass list, and I'm having trouble determining what
> special methods I have to override in my class for the above two
> operations.  From my testing, it seems to be __setslice__ for both,
> but the docs say __setslice__ and brethren are deprecated.  I would
> have thought that __setitem__ and __delitem__ would be what was
> called, but again, my testing says otherwise.

It is a combination. http://docs.python.org/ref/sequence-methods.html

For setting a slice in the form `x[from:to] = seq` the __setslice__
method will be called if it exists:
 x.__setslice__(from, to, seq)

if __setslice__ doesn't exists __setitem__ is called with a slice
object:
 x.__setitem__(slice(from,to), seq)

if setting a slice in the form `x[from:to:step] = seq` (extended
slicing) __setitem__ will be called with a slice object:
 x.__setitem__(slice(from, to, step), seq)

For non slices (single index values) __setitem__ is always called.

The real problem, and someone correct me if I'm wrong (this is a
newsgroup... of course they will :p), is that you can't make your
class hide or get rid of __setslice__ on the base class. I've tried
making __getattribute__ raise an AttributeError and making __hasattr__
return False, neither works. I think this is because list is
implemented in C and the __setslice__ slot is filled. Because the list
object is implemented in C and is optimized, it doesn't use
__getattribute__ or __hasattr__ to find out if the slice method
exists, Python just grabs the pointer from the c structure and uses
it.

In my examples I only mentioned __setslice__/__setitem__, but all the
same should apply to __delslice__/__delitem__ as well.

So, it looks like as long as you want to subclass list, you are stuck
implementing both __*slice__ and __*item__ methods.

Matt



More information about the Python-list mailing list