Pergunta

Eu quero criar um conjunto personalizado que irá converter automaticamente objetos em uma forma diferente para armazenamento no conjunto (ver Usando um dicionário Python como uma chave não aninhado) para o fundo.

Se eu substituir add, remove, __contains__, __str__, update, __iter__, será isso suficiente para fazer as outras operações comportar corretamente, ou que eu preciso para substituir qualquer outra coisa?

Foi útil?

Solução

Trabalho de classes abstratas de collections, como @ kaizer.se sugere, é a solução adequada em 2,6 (não sei por que você quer chamar de super - o que a funcionalidade que você está tentando delegar que não pode o melhor feito por contenção em vez de herança?!).

É verdade que você não obter update - fornecendo os métodos abstratos, você começa __le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__ __sub__, __xor__, and isdisjoint (de collections.Set) mais clear, pop, remove, __ior__, __iand__, __ixor__, and __isub__ (de collections.MutableSet), que é muito mais do que você deseja obter a partir subclasse set (onde você 'teria que substituir todas método de juros). Você só terá que fornecer outros métodos set que você deseja.

Note que as classes base abstratas como collections.Set são um animal muito diferente de classes concretas, incluindo builtins como set e (em 2.6) boa sets.Set velha, obsoleta, mas ainda em torno de (removido em Python 3). ABCs são destinados a herdar a partir de (e pode, então, sintetizar alguns métodos de você uma vez que você implementar todos os métodos abstratos, como você deve) e, secundariamente, para "registrar" as classes com que eles olham como se eles herdaram a partir deles, mesmo quando não o fazem (para fazer isinstance mais utilizável e útil).

Aqui está um exemplo de trabalho para Python 3.1 e 2.6 (sem boa razão para usar 3.0, como 3.1 só tem vantagens sobre ele, nenhuma desvantagem):

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

Outras dicas

Em Python 2.6:

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

subclasse collections.MutableSet e substituir os métodos na lista acima.

o próprio método de atualização é muito fácil, uma vez que o mínimo acima é implementado

def update(self, iterable):
    for x in iterable:
        self.add(x)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top