在实现自定义列表时(通过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
,我还应该重写其他什么方法?
答案 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
容器中并返回。否则,如果是单个元素,则将其传回。