覆盖Python中的set方法

Overriding set methods in Python

我想创建一个自定义集,它将自动将对象转换为另一种形式,以便在该集中存储(请参见使用Python字典作为非嵌套键)作为背景。

如果我覆盖addremove__contains____str__update__iter__,这是否足以使其他操作正常运行,还是需要覆盖其他操作?


正如@kaizer.se所建议的,使用collections的抽象类是2.6中的合适解决方案(不确定为什么要调用super——您试图委托哪些功能不能最好地通过包含而不是继承来完成?!!)

的确,你没有得到update--通过提供抽象的方法,你得到了__le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__ __sub__, __xor__, and isdisjoint(来自collections.Set)加上clear, pop, remove, __ior__, __iand__, __ixor__, and __isub__(来自collections.MutableSet),这比你从set子类得到的要多得多(你必须覆盖所有感兴趣的方法)。你只需要提供你想要的其他方法。

请注意,像collections.Set这样的抽象基类与具体类是非常不同的,包括诸如set和(在2.6中)很好的旧sets.Set这样的内置类,尽管已弃用,但仍然存在(在python 3中删除)。ABC是从继承(然后可以在实现所有抽象方法后合成一些方法,正如您必须的那样),其次是用"注册"类,这样即使它们不继承,它们看起来也像是从它们继承的(使isinstance更有用)。

下面是Python3.1和2.6的一个工作示例(没有充分的理由使用3.0,因为3.1只比它有优势,没有劣势):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import collections

class LowercasingSet(collections.MutableSet):
  def __init__(self, initvalue=()):
    self._theset = set()
    for x in initvalue: self.add(x)
  def add(self, item):
    self._theset.add(item.lower())
  def discard(self, item):
    self._theset.discard(item.lower())
  def __iter__(self):
    return iter(self._theset)
  def __len__(self):
    return len(self._theset)
  def __contains__(self, item):
    try:
      return item.lower() in self._theset
    except AttributeError:
      return False


在Python 2.6中:

1
2
3
4
import collections
print collections.MutableSet.__abstractmethods__
# prints:
# frozenset(['discard', 'add', '__iter__', '__len__', '__contains__'])

子类collections.MutableSet并重写上面列表中的方法。

更新方法本身非常简单,因为实现了上面的最小值。

1
2
3
def update(self, iterable):
    for x in iterable:
        self.add(x)