Настройте Python Slicing, пожалуйста, сообщите - PullRequest
7 голосов
/ 25 февраля 2011

У меня есть класс, который подклассов объекта списка.Теперь мне нужно заняться нарезкой.Из всего, что я прочитал в трубках, это должно быть сделано методом __getitem__.По крайней мере, в Python 2.7+, который я использую.Я сделал это (см. Ниже), но метод __getitem__ не вызывается при передаче фрагмента.Вместо этого срез сделан, и список возвращен.Я хотел бы вернуть новый экземпляр myList.

Пожалуйста, помогите мне выяснить, в чем дело.

Спасибо!

class myList(list):

    def __init__(self, items):

        super(myList, self).__init__(items)
        self.name = 'myList'


    def __getitem__(self, index):

        print("__getitem__")
        if isinstance(index, slice):
            print("slice")
            return self.__class__(
                self[x] for x in range(*index.indices(len(self)))
                )
        else: return super(myList, self).__getitem__(index)

if __name__ == "__main__":
    print("\nI'm tesing out custom slicing.\n")

    N = 10
    L = myList(range(N))

    L3 = L[3]
    L02 = L[:2]

1 Ответ

17 голосов
/ 25 февраля 2011

См. эту заметку :

object.__getslice__(self, i, j)

Устаревший с версии 2.0: Поддержка нарезать объекты в качестве параметров __getitem__() метод. (Тем не менее, встроенные типы в CPython в настоящее время все еще реализуем __getslice__(). Следовательно, вы должны переопределить его в производные классы при реализации нарезка.

Итак, поскольку вы подкласс list, вы должны перезаписать __getslice__, даже если это устарело.

Я думаю, что вы должны избегать подклассов встроенных функций, слишком много странных деталей. Если вам нужен класс, который ведет себя как список, в этом вам поможет ABC :

from collections import Sequence

class MyList(Sequence):
    def __init__(self, *items):
        self.data = list(items)

    def __len__(self):
        return len(self.data)

    def __getitem__(self, slice):
        return self.data[slice]

s = MyList(1,2,3)
# lots of free methods
print s[1:2], len(s), bool(s), s.count(3), s.index(2), iter(s)
...