Sostituzione dei metodi impostati in Python
-
06-07-2019 - |
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?
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 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)