You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义UserList切片返回list而非派生类的问题及解决咨询

Fixing Custom UserList Slice & Operation Return Types

Great question! The issue you're facing is that UserList's default behavior returns a regular list for slice operations (and some other list-producing actions) instead of your custom myList class. This breaks access to your custom methods like getFunc() because the returned object isn't an instance of your subclass.

Root Cause

Under the hood, UserList delegates most operations to its internal self.data attribute (a plain Python list). When you slice a UserList, it slices self.data directly and returns that plain list, skipping your custom class entirely.

Elegant Solution: Override Key Methods

Instead of manually converting results to myList every time, you can encapsulate this logic within your class by overriding methods that return new list-like objects. Here's how to do it properly:

Updated myList Class

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
    
    def __getitem__(self, item):
        # Get the result from the parent class
        result = super().__getitem__(item)
        # If it's a slice, wrap it in our custom class
        if isinstance(item, slice):
            return self.__class__(result)
        # For single indices, return the item as-is
        return result
    
    def __add__(self, other):
        # Return a new myList instance after addition
        return self.__class__(super().__add__(other))
    
    def __mul__(self, n):
        # Return a new myList instance after multiplication
        return self.__class__(super().__mul__(n))
    
    def __rmul__(self, n):
        # Handle reverse multiplication (e.g., 2 * myList)
        return self.__class__(super().__rmul__(n))
    
    def copy(self):
        # Return a new myList instance instead of a plain list
        return self.__class__(self.data.copy())

Why This Works

  • __getitem__: Checks if the operation is a slice. If so, it takes the plain list result from UserList and wraps it in a myList instance (using self.__class__ instead of hardcoding myList makes this class reusable for subclasses).
  • __add__/__mul__/__rmul__: These methods handle arithmetic operations that produce new lists, ensuring the result is always a myList.
  • copy(): Overrides the default copy behavior to return a myList instead of a plain list.

Test the Updated Class

Let's run your original test code with the updated class:

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

# Additional tests to verify other operations
l3 = l1 + [5,6]
print(type(l3))
l4 = l1 * 2
print(type(l4))
l5 = l1.copy()
print(type(l5))

Output

<class '__main__.myList'>
<class '__main__.myList'>
[1, 2, 3]
<class '__main__.myList'>
<class '__main__.myList'>
<class '__main__.myList'>

No more AttributeError! All operations now return myList instances, so you can use your custom methods seamlessly.

Bonus: Why Not Just myList(l1[:3])?

While manual conversion works for one-off cases, overriding these methods is far more elegant because:

  • It's encapsulated: Users of your class don't have to remember to convert types every time.
  • It's consistent: Every list-producing operation behaves the same way.
  • It's maintainable: You only need to update the logic in one place if your class changes.

内容的提问来源于stack exchange,提问作者bivouac0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:47:46