Python:我该如何在这个类中实现'pop'?

1 投票
4 回答
2482 浏览
提问于 2025-04-15 14:08

我希望这个类能像列表一样工作。它的数据存储在属性 self.data 中。如果我有一个实例,叫做 pp = population,定义 __getitem__ 是不是就意味着我可以直接用 pp 来代替 pp.data?还是说是定义 __repr__ 才能做到这一点?另外,如果我让这个类继承自列表而不是普通对象,是否就能直接使用 'pop' 方法?现在我需要自己实现 'pop' 方法。谢谢!

class population (object):
def __init__ (self):
    self.data = []

def append(self, item):
    self.data.append(item)

def extend(self, item):
    self.data.extend(item)

def sort(self):
    self.data.sort(cmp=fitnesscompare)

def __getitem__(self, index): return self.data[index]

def __setitem__(self, index, item): self.data[index] = item

def __len__(self): return len(self.data)

def __repr__(self): return repr(self.data)

def copy(self):
    return copy.deepcopy(self)

4 个回答

1

如果我有一个实例,pp = population,定义了 __getitem__ 是不是就可以用 pp 来代替 pp.data 呢?

基本上是的。添加一个 __getitem__ 方法就像是在其他一些语言中重载了 [] 操作符。因此,下面这两种写法是等价的:

pp.data[0]
pp[0]

那么,是定义 __repr__ 实现这个功能吗?

定义 __repr__ 会给你一个对象的字符串表示。所以这两种调用方式也是等价的:

repr(pp.data)
repr(pp)

如果我让这个类继承自 list 而不是 object,会不会让我有 'pop' 方法?

从我现在看到的情况来看,继承自 list 可能是更好的选择。除非我漏掉了什么,不然唯一不同的就是排序方法和复制。其他几乎都是一样的。

3
def pop(self, index=-1) :
    return self.data.pop(index)

这段代码会实现预期的功能:

  • 如果没有传入索引,就返回最后一个项目;
  • 如果传入了“索引”,就返回对应索引的项目;
  • 会使用底层 pop() 的类型检查;
  • 会抛出和底层 pop() 一样的异常。

我本来可以像Evan Fosmark建议的那样去子类化List,但我也明白不这样做的好理由。使用组合可以降低耦合度,你对它有完全的控制权。不过,你需要为所有想要委托的方法写桥接代码,这可能会很麻烦……

8

为什么不直接扩展列表类呢?这样你就可以直接拥有所有的功能了。

class population(list):
    # custom methods here

记住,引用列表的时候,不要用 self.data,而是直接用 self

撰写回答