题
我想创建一个自定义集,它会自动将对象转换为另一种形式以便存储在集合中(参见使用Python字典作为非嵌套键)用于后台。
如果我覆盖 add
, remove
, __ contains __
, __ str __
, update
, __ iter __
,这足以使其他操作正常运行,还是我需要覆盖其他任何操作?
解决方案
正如@ kaizer.se建议的那样,使用 collections
的抽象类是2.6中的适当解决方案(不确定为什么要调用super - 你试图委派哪些功能?不能通过遏制而不是继承来做到最好吗?!)。
确实你没有得到 update
- 通过提供抽象方法,你得到 __ le __,__ lt __,__ eq __,__ ne__,__ gt__,__ ge__,__ and__,__ or__ _ _ _ _ 9,_ __xor __和isdisjoint
(来自 collections.Set
)加上 clear,pop,remove,__ _1 _,_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ MutableSet
),远远超过你从子类化 set
得到的(你必须覆盖感兴趣的每个方法)。你只需要提供你想要的其他设定方法。
请注意,像 collections.Set
这样的抽象基类是一个与具体类完全不同的野兽,包括内置函数,如 set
和(在2.6中)旧的 sets.Set
,已弃用但仍在(在Python 3中删除)。 ABCs意味着继承(并且一旦你实现所有的抽象方法,你可以合成一些方法,你必须),其次是“注册”。这些类看起来好像是从它们继承而且它们没有(为了使 isinstance
更有用和有用)。
这是Python 3.1和2.6的一个工作示例(没有充分理由使用3.0,因为3.1只有优势,没有缺点):
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中:
import collections
print collections.MutableSet.__abstractmethods__
# prints:
# frozenset(['discard', 'add', '__iter__', '__len__', '__contains__'])
子类 collections.MutableSet
并覆盖上面列表中的方法。
更新方法本身非常简单,只要实现上述最低要求
def update(self, iterable):
for x in iterable:
self.add(x)