我需要覆盖Python的列表函数吗?

5

我有一个类DataSet,它继承了Python中的list类:

class DataSet(list):

    def __init__(self, *args):
        super(DataSet, self).__init__(*args)

现在我可以创建此类的实例并打印类型。

data = DataSet([0, 1, 2, 3, 4])
print(type(data))
>>> <class 'DataSet'>

然而,当我想要获取这个 DataSet 的子集并打印类型时,会得到以下输出:

data2 = data[2:4]
print(type(data2))
>>> <class 'list'>

由于我没有重写list__getitem__方法,所以会出现这种情况。Python的list类有许多可以重写以使用的方法,但作为程序员,我只想做的是让所有这些通常返回list类型实例的方法现在返回DataSet类型的实例。是否有一种方法可以实现这一点,而无需手动重写所有这些函数?还是我必须手动覆盖所有这些方法?

1
是的,你必须手动完成它,但为什么要继承自list呢? - juanpa.arrivillaga
2
你计划为你的 DataSet 添加任何有意义的东西吗?目前我看不出用那种方式包装列表的好处。继承列表(_IsA_)可能不是正确的方法,也许将列表作为内部成员(_HasA_)更好地模拟你的关注点。或者你可以使用适用于列表的工具方法。 - Patrick Artner
是的,我计划对 DataSet 进行有意义的操作。更具体地说,我想使用它来容纳我自己的类 DataPoint 的实例,该类由时间戳和值组成。 DataSet 包含可以轻松处理此 DataPoint 类的计算方法,例如欧拉微分。我认为继承列表类会起作用,因为它具有所有这些内置方法,但现在我最终必须覆盖它们,因此在这种情况下,HasA 可能更有效。 - suitendaal
1
为什么不继承自collections.UserList呢?它基本上是为了避免直接继承list而设计的,因为list有各种令人惊讶的副作用。我认为这也应该解决你的“类型”问题。 - Timus
1
通常情况下,您应该优先选择组合而非继承。 - juanpa.arrivillaga
1个回答

0
你要求的并非不可能。通过迭代所有返回数组的函数并使用装饰器将输出更改为所需输出,这很容易实现。如果你手动研究并处理这些函数,你会学到更多。
class DataSet(list):

    def __init__(self, *args):
        super(DataSet, self).__init__(*args)
#that where we must use decorator and loop over all builin functions
def  DataSet_evo(func):
    
    from inspect import signature
    
    def new_func(*args):
     res=func(*args)   
     if type(res)==type([])  :
      return DataSet(res)
     else:
      return res  #for example pop() it return element so it will throw eror as it not list 
         
   
    return new_func

for i in dir(DataSet):
 if i not in ["__init__","__class__"]:   
  try:   
   line="DataSet."+i+"="+"DataSet_evo(list."+i+")"   
   exec(line)
  except:
     pass# for handling .__class__ in dir
   
data = DataSet([0, 1, 2, 3, 4])
print(type(data))        
data2 = data[2:4]
print(type(data2))

愉快编码


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接