Domanda
ZODB fornisce un PersistentList
e un PersistentMapping
, ma mi piacerebbe un PersistentSet
.Ho scritto un rapido classe che rispecchia l'antica PersistentList
da ZODB 2.Perché non c'è UserSet
in Python, ho dovuto prolungare il C-in base built-in set
.
class PersistentSet(UserSet, Persistent):
def __iand__(self, other):
set.__iand__(other)
self._p_changed = 1
...
...
...
def symmetric_difference_update(self, other):
set.symmetric_difference_update(other)
self._p_changed = 1
Codice prodotto un "di più basi di istanza di lay-out conflitto" errore.Ho cercato di creare un UserSet
wrapper set
, ma che non ha risolto il problema.
class UserSet(set):
def __init__(self):
self.value = set
def __getattribute__(self, name):
return self.value.__getattribute__(name
Infine, ho importato sets.Set
(rimpiazzato da il built-in set
), ma che sembra essere implementato in C, troppo.Non ho trovato nessun set implementazioni su PyPI quindi sono in un vicolo cieco ora.
Quali sono le mie opzioni? Dovrei implementare un set da zero o utilizzare UserDict
e buttare via tutti i value
s.
Soluzione
Perché non utilizzare la persistente set di classe fornito con il BTree librerie in ZODB.Ci sono 4 classi disponibili.IITreeSet e IOTreeSet di gestire insiemi di numeri interi e OITreeSet e OOTreeSet gestire set di oggetti arbitrari.Essi corrispondono alle quattro BTree classi IIBTree, IOBTree, OIBTree e OOBTree rispettivamente.I loro vantaggi rispetto l'implementazione di set costruito in Python sono loro veloce meccanismo di ricerca (thanx per il sottostante b-tree) e la loro persistenza di supporto.
Ecco qualche esempio di codice:
>>> from BTrees.IIBTree import IITreeSet, union, intersection
>>> a = IITreeSet([1,2,3])
>>> a
<BTrees._IIBTree.IITreeSet object at 0x00B3FF18>
>>> b = IITreeSet([4,3,2])
>>> list(a)
[1, 2, 3]
>>> list(b)
[2, 3, 4]
>>> union(a,b)
IISet([1, 2, 3, 4])
>>> intersection(a,b)
IISet([2, 3])
Altri suggerimenti
In avanti tutto l'attributo richieste per l'allestimento interno:
class PersistentSet(Persistent):
def __init__(self):
self.inner_set = set()
def __getattribute__(self, name):
try:
inner_set = Persistent.__getattribute__(self, "inner_set")
output = getattr(inner_set, name)
except AttributeError:
output = Persistent.__getattribute__(self, name)
return output
Per future letture, volevo solo offrire un lieve miglioramento rispetto al già proposto risposte...
Personalizzato persistente set di classe
class PersistentSet(Persistent):
def __init__(self, *args, **kwargs):
self._set = set(*args, **kwargs)
def __getattr__(self, name):
return getattr(self._set, name)
Persistente set di classe dalla libreria
from BTrees.OOBTree import OOSet
Vedi anche