2009-05-17 8 views
3

ZODB fournit un PersistentList et un PersistentMapping, mais j'aimerais un PersistentSet. J'ai écrit une classe rapide qui reflète l'ancien PersistentList de ZODB 2. Parce qu'il n'y a pas UserSet en Python, j'ai dû étendre à partir de la set intégré C-based.PersistentSet dans ZODB 3

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 

Le code produit un "plusieurs bases ont par exemple un conflit lay-out" error. J'ai essayé de créer un wrapper UserSet autour de set, mais cela n'a pas résolu le problème non plus.

class UserSet(set): 
    def __init__(self): 
     self.value = set 
    def __getattribute__(self, name): 
     return self.value.__getattribute__(name 

Enfin, je sets.Set importé (remplacé par le set intégré), mais qui semble être mis en œuvre en C, aussi. Je n'ai trouvé aucune implémentation sur PyPI, donc je suis dans une impasse maintenant.

Quelles sont mes options? Je peux avoir à mettre en œuvre un ensemble à partir de zéro ou utiliser UserDict et jeter tous les value s.

Répondre

3

Pourquoi ne pas utiliser la classe ensemble persistant fourni avec les bibliothèques BTree ZODB. Il y a 4 classes de ce type disponibles. IITreeSet et IOTreeSet gèrent des ensembles d'entiers et OITreeSet et OOTreeSet gèrent un ensemble d'objets arbitraires. Ils correspondent respectivement aux quatre classes BTree IIBTree, IOBTree, OIBTree et OOBTree. Leurs avantages par rapport à l'implémentation de l'ensemble construit en Python sont leur mécanisme de recherche rapide (merci au BTree sous-jacent) et leur support de persistance.

Voici quelques exemples de code:

>>> 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]) 
+0

En fait, 'IITreeSet' ne fonctionne qu'avec des éléments entiers ... –

1

Transférer tous les attributs des demandes de l'ensemble interne:

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 
+0

Votre solution fonctionne, mais je fait un changement de couple. J'ai ajouté * args au constructeur, et j'ai ajouté self._p_changed = 1 à la fin du bloc try ... Je ne suis pas sûr que ce soit inutile ou s'il a été accidentellement omis dans la réponse. Merci. –

+0

@Nikhil, c'est un raccourci facile. Vous supposerez simplement que chaque accès à une variable modifie les données. Si vous voulez que ce soit parfait, enveloppez chaque méthode qui change l'ensemble avec soi-même._p_changed = 1 – Unknown

1

Pour les lectures futures, je voulais juste offrir une légère amélioration par rapport aux réponses déjà proposées ...

classe PREF persistante

class PersistentSet(Persistent): 

    def __init__(self, *args, **kwargs): 
     self._set = set(*args, **kwargs) 

    def __getattr__(self, name): 
     return getattr(self._set, name) 

Classe d'ensemble persistante de la bibliothèque

from BTrees.OOBTree import OOSet 

Voir aussi