Subclassing list, what special methods do this?

M

Mike Kent

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

Gabriel Genellina

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.

__setslice__ and __delslice__, *and* __setitem__/__delitem__ for extended
slice notation.
The first two are deprecated, but since the list type implements them you
have to do the same, because the interpreter invokes those methods when
they exist, even if found in a base class.
 
M

Matimus

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
 
M

Mike Kent

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

Matt

Thanks. That was clear and concise, just what I needed.
 
T

Terry Reedy

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

Unless writing in 3.0, where they have finally disappeared.
 
P

Paul McGuire

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.

Or you could forget this "subclassing" stuff, and just implement
__setitem__, __getitem__, __delitem__, __len__, and __iter__ in your
own class, and not worry about what list does or doesn't do. You
could have your class contain a list to implement with, and then
delegate to it from your class's code.

Overall, I think Python as a language favors composition/delegation
over inheritance - c/d is so easy to do with __getattribute__, and
inheritance is largely unnecessary since type/interface is not checked
until runtime. Yet many O-O texts are written around C++ and Java's
static type models, so we see a preponderance of patterns and
conventional O-O wisdom recommending inheritance. For Python, it
ain't necessarily so...

-- Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,817
Latest member
AdalbertoT

Latest Threads

Top