__setslice__ and classes derived from list

Dave Opstad opstad at batnet.com
Fri Sep 2 10:41:34 EDT 2005


According to the documentation the __setslice__ method has been 
deprecated since Python 2.0. However, if I'm deriving classes from the 
builtin list class, I've discovered I can't really ignore __setslice__. 
Have a look at this snippet:

----------------------------------------------------
>>> class V(list):
...   def __setitem__(self, key, value):
...     if isinstance(key, slice):
...       print "Slice:", key.start, key.stop, key.step
...     else:
...       print "Regular:", key
...     super(V, self).__setitem__(key, value)
...   def __setslice__(self, i, j, value):
...     print "Old method:", i, j
...     super(V, self).__setslice__(i, j, value)
... 
>>> v = V([1,2,4,8])
>>> v
[1, 2, 4, 8]
>>> v[0] = 100
Regular: 0
>>> v
[100, 2, 4, 8]
>>> v[1:3] = [99, 99]
Old method: 1 3
>>> v           
[100, 99, 99, 8]
>>> v[1:3:1] = [88, 88]
Slice: 1 3 1
>>> v
[100, 88, 88, 8]
>>> v[-1] = 12
Regular: -1
>>> v   
[100, 88, 88, 12]
>>> v[-3:-1] = [77, 66]
Old method: 1 3
>>> v
[100, 77, 66, 12]
----------------------------------------------------

If I assign to v[1:3] it dispatches via __setslice__, but if I assign to 
v[1:3:1] it dispatches via __setitem__. The documentation states that if 
a __setslice__ method is present it will be used, but if one isn't 
present then a slice will be synthesized and __setitem__ will be used 
exclusively. Since the builtin list class provides a __setslice__ 
method, what this means is that any class derived from list still has to 
make provisions for this ostensibly deprecated method.

There's a workaround for this, namely to include this method:

    def __setslice__(self, i, j, seq):
        self.__setitem__(slice(i, j), seq)

That way any custom code I need to include in __setitem__ doesn't have 
to be duplicated in __setslice__. But just out of curiosity I thought 
I'd ask the folks here if there's any other way of doing this? Maybe 
something like a "noslicelist" class which doesn't have __setslice__, 
where the standard list class would then be a subclass of noslicelist 
with the __setslice__ method present for compatibility. That way I could 
subclass noslicelist myself, and not have to worry about it.

Dave



More information about the Python-list mailing list