List slicing on Python 2.7

Ned Batchelder ned at nedbatchelder.com
Thu Mar 15 16:28:41 EDT 2018


On 3/15/18 12:35 PM, Peter Otten wrote:
> Ned Batchelder wrote:
>
>> On 3/15/18 9:57 AM, Vlastimil Brom wrote:
>>> 2018-03-15 12:54 GMT+01:00 Arkadiusz Bulski <arek.bulski at gmail.com>:
>>>> I have a custom class (a lazy list-like container) that needs to support
>>>> slicing. The __getitem__ checks if index is of slice type, and does a
>>>> list comprehension over individual integer indexes. The code works fine
>>>> on Python 3 but fails on 2.7, both CPython and PyPy. The print inside
>>>> __getitem__ doesnt even get executed when its a slice. Does 2.7 have
>>>> different object model, where slices are handled by a different method
>>>> than __getitem__?
>>>>
>>>> The implementation and error log
>>>>
> https://github.com/construct/construct/blob/8839aac2b68c9e8240e9d9c041a196b0a7aa7d9b/construct/core.py#L4785-L4796
> https://github.com/construct/construct/blob/8839aac2b68c9e8240e9d9c041a196b0a7aa7d9b/tests/test_core.py#L1148
>>>> https://travis-ci.org/construct/construct/jobs/353782126#L887
>>>>
>>>> --
>>>> ~ Arkadiusz Bulski
>>>> --
>>>> https://mail.python.org/mailman/listinfo/python-list
>>> Hi,
>>> it looks like, the older method __getslice__ is still used in python 2.7
>>> cf.:
>>> https://docs.python.org/2/reference/datamodel.html#object.__getslice__
>>>
>>> You might need to implement this method in your class as well for
>>> compatibility with python 2.
>>>
>>>
>> Python 2 will use __getitem__ for slices:
>>
>>   $ python2.7
>>   Python 2.7.10 (default, May 30 2015, 12:06:13)
>>   [GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
>>   Type "help", "copyright", "credits" or "license" for more information.
>>   >>> class Sliceable(object):
>>   ...     def __getitem__(self, thing):
>>   ...         print type(thing)
>>   ...         print thing
>>   ...
>>   >>> Sliceable()[1:5]
>>   <type 'slice'>
>>   slice(1, 5, None)
>>   >>> Sliceable()[:]
>>   <type 'slice'>
>>   slice(None, None, None)
>>   >>>
> __getslice__() takes precedence, and the OP subclasses list:
>
> $ python
> Python 2.7.6 (default, Nov 23 2017, 15:49:48)
> [GCC 4.8.4] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>>>> class A(list):
> ...     def __getitem__(self, index): return index
> ...
>>>> a = A()
>>>> a[:]
> []
>>>> a[::]
> slice(None, None, None)
>>>> A.__getslice__ = lambda self, *args: args
>>>> a[:]
> (0, 9223372036854775807)
>
>

Another good reason not to subclass list.

--Ned.



More information about the Python-list mailing list