切片将UserList转换为列表

时间:2019-01-30 15:21:44

标签: python collections

在实现自定义列表时(通过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 :(得分:0)

我不确定为什么这不是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容器中并返回。否则,如果是单个元素,则将其传回。