Нарезка преобразует UserList в список - PullRequest
0 голосов
/ 30 января 2019

При реализации пользовательского списка (через UserList) я заметил, что все операции среза возвращают тип list, а не тип производного класса.Это создает проблему, из-за которой после нарезки ни одна из добавленных функциональных возможностей не доступна в объекте.Вот программа быстрого тестирования, чтобы продемонстрировать проблему, просто обратите внимание, что сам код более сложен.

#!/usr/bin/python3
from collections import UserList

class myList(UserList):
    def __init__(self, data=None):
        super().__init__(data)
    def setFunc(self, data):
        self.data.extend(data)
    def getFunc(self):
        return self.data

l1 = myList()
l1.setFunc([1,2,3,4])
print(type(l1))
l2 = l1[:3]
print(type(l2))
print(l2.getFunc())

<class '__main__.myList'>
<class 'list'>
Traceback (most recent call last):
  File "./test.py", line 17, in <module>
    print(l2.getFunc())
AttributeError: 'list' object has no attribute 'getFunc'

Я могу преодолеть эту проблему, «приведя» list к l2 = myList(l1[:3]), но кажетсякак правильное решение было бы реализовать эту функцию непосредственно в myList.

Я не уверен, что правильный / самый элегантный способ сделать это.Я подозреваю, что использование броска в __getitem__ будет работать.Это лучший способ или есть более прямое изменение в нарезке, которое было бы предпочтительным?Кроме того, какие другие методы я должен переопределить, чтобы все операции возвращали myList, а не list?

1 Ответ

0 голосов
/ 30 января 2019

Я не уверен, почему это не поведение по умолчанию в UserList, но реализация следующего в производном классе, кажется, решает проблему.

def __getitem__(self, i):
    new_data = self.data[i]
    if type(new_data) == list:
        return self.__class__(new_data)
    else:
        return new_data

Параметр i для __getitem__ может быть либо slice объектом, либо целым числом, поэтому new_data будет либо list, либо отдельным элементом.Если это list, поместите его в контейнер myList и вернитесь.В противном случае, если это один элемент, просто передайте его обратно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...