Domanda

Voglio creare un set personalizzato che convertirà automaticamente gli oggetti in una forma diversa per l'archiviazione nel set (vedi Utilizzo di un dizionario Python come chiave non nidificata ) per lo sfondo.

Se eseguo l'override di aggiungi , rimuovi , __contains__ , __str__ , aggiorna , __iter__ , sarà sufficiente per fare in modo che le altre operazioni si comportino correttamente o devo scavalcare qualcos'altro?

È stato utile?

Soluzione

Lavorare dalle classi astratte di collezioni , come suggerisce @ kaizer.se, è la soluzione appropriata in 2.6 (non sono sicuro del motivo per cui vuoi chiamare super - quale funzionalità stai cercando di delegare che non può essere fatto meglio dal contenimento anziché dall'eredità ?!).

È vero che non ottieni update : fornendo i metodi astratti, ottieni __le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__ __sub__, __xor__ e isdisjoint (dalle raccolte Impostate ) più cancella, pop, rimuovi, __ior__, __iand__, __ixor__ e __isub__ (dalle raccolte . MutableSet ), che è molto più di quanto otterresti dalla sottoclasse set (dove dovresti scavalcare ogni metodo di interesse). Dovrai solo fornire altri metodi impostati che desideri.

Nota che le classi di base astratte come collezioni.Set sono una bestia piuttosto diversa dalle classi concrete, inclusi builtin come set e (in 2.6) buon vecchio sets.Set , obsoleto ma ancora in circolazione (rimosso in Python 3). Le ABC sono destinate a ereditare da (e possono quindi sintetizzare alcuni metodi da te una volta implementati tutti i metodi astratti, come è necessario) e secondariamente a "registrare". le classi con così sembrano ereditate da loro anche quando non lo fanno (per rendere isinstance più utilizzabili e utili).

Ecco un esempio funzionante per Python 3.1 e 2.6 (nessuna buona ragione per usare 3.0, dato che 3.1 ha solo vantaggi, nessun svantaggio):

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

Altri suggerimenti

In Python 2.6:

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

subclass collections.MutableSet e sovrascrive i metodi nell'elenco sopra.

il metodo di aggiornamento stesso è molto semplice, dato che è implementato il minimo indispensabile sopra

def update(self, iterable):
    for x in iterable:
        self.add(x)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top