简体   繁体   中英

Slicing converts UserList to list

While implementing a custom list (via UserList ) I noticed that all slicing operations return a type of list not of the derived class type. This creates an issue that, after slicing, none of the added functionality is available in the object. Here is a quick test program to demonstrate the issue, just note the the actual code is more complicated.

#!/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'

I can overcome this issue by "casting" the list with l2 = myList(l1[:3]) but it seems like the right solution would be to implement this functionality directly in myList .

I'm not certain the correct/most-elegant way to do this. I suspect putting a cast in __getitem__ would work. Is that the best way or is there a more direct change to the slicing that would be preferred? Also, what other methods should I override in order to assure all operations return a myList not a list ?

I'm not sure why this isn't the default behavior in UserList but implementing the following in the derived class seems to fix the issue.

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

The parameter i for __getitem__ apparently can be either a slice object or an integer so new_data will either be a list or a single element. If it's a list put it in the myList container and return. Otherwise, if it's a single element, just pass that back.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM