Как создать подкласс списка Python без проблем с типами? - PullRequest
31 голосов
/ 18 ноября 2011

Я хочу реализовать пользовательский класс списка в Python как подкласс list.Какой минимальный набор методов мне нужно переопределить из базового класса list, чтобы получить полную совместимость типов для всех операций со списками?

Этот вопрос предполагает, что по крайней мере __getslice__ должен быть переопределен.От дальнейших исследований также потребуются __add__ и __mul__.Итак, у меня есть этот код:

class CustomList(list):
    def __getslice__(self,i,j):
        return CustomList(list.__getslice__(self, i, j))
    def __add__(self,other):
        return CustomList(list.__add__(self,other))
    def __mul__(self,other):
        return CustomList(list.__mul__(self,other))

Следующие операторы работают по желанию, даже без переопределяющих методов:

l = CustomList((1,2,3))
l.append(4)                       
l[0] = -1
l[0:2] = CustomList((10,11))    # type(l) is CustomList

Эти операторы работают только с переопределяющими методами в приведенном выше определении класса:

l3 = l + CustomList((4,5,6))    # type(l3) is CustomList
l4 = 3*l                        # type(l4) is CustomList
l5 = l[0:2]                     # type(l5) is CustomList

Единственное, чего я не знаю, как добиться, это заставить расширенную нарезку возвращать правильный тип:

l6 = l[0:2:2]                   # type(l6) is list

Что мне нужно добавить к определению моего класса вчтобы получить CustomList как тип l6?

Кроме того, есть ли другие операции со списками, кроме расширенного среза, где результат будет иметь тип list вместо CustomList?

Ответы [ 2 ]

22 голосов
/ 18 ноября 2011

Во-первых, я рекомендую вам следовать совету Бьёрна Поллекса (+1).

Чтобы обойти эту конкретную проблему (type(l2 + l3) == CustomList), вам необходимо реализовать пользовательский __add__():

   def __add__(self, rhs):
        return CustomList(list.__add__(self, rhs))

А для расширенная нарезка :

    def __getitem__(self, item):
        result = list.__getitem__(self, item)
        try:
            return CustomList(result)
        except TypeError:
            return result

Я также рекомендую ...

pydoc list

... в вашей командной строке.Вы увидите, какие методы list предоставляет, и это даст вам хорошее представление о том, какие из них вам нужно переопределить.

20 голосов
/ 18 ноября 2011

Возможно, вам следует прочитать эти два раздела из документации:

Редактировать: Чтобы обрабатывать расширенные срезы, вы должны создать __getitem__ -метод, работающий с слайс-объектами (см. здесь , чуть дальше).

...