2009-05-17 1 views
3

ZODB bietet eine PersistentList und eine PersistentMapping, aber ich möchte eine PersistentSet. Ich schrieb eine schnelle Klasse, die die alte PersistentList von ZODB 2 widerspiegelt. Da es keine UserSet in Python gibt, musste ich von der C-basierten integrierten set erweitern.PersistentSet in 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 

Der Code erzeugte eine error "mehr Basen Instanz Lay-out-Konflikt". Ich habe versucht, einen UserSet Wrapper um set zu erstellen, aber das hat das Problem auch nicht gelöst.

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

Schließlich habe ich importiert sets.Set (ersetzt durch die eingebaute in set), aber das scheint in C auch umgesetzt werden. Ich habe keine Set-Implementierungen auf PyPI gefunden, also bin ich jetzt in einer Sackgasse.

Was sind meine Optionen? Ich muss ein Set von Grund auf neu implementieren oder UserDict verwenden und alle value s wegwerfen.

Antwort

3

Warum Sie nicht verwenden, um die persistente Set-Klasse mit den BTree Bibliotheken in ZODB zur Verfügung gestellt. Es gibt 4 solcher Klassen. IITreeSet und IOTreeSet verwalten Mengen von Integern und OITreeSet und OOTreeSet verwalten eine Menge von beliebigen Objekten. Sie entsprechen den vier BTree-Klassen IIBTree, IOBTree, OIBTree bzw. OOBTree. Ihre Vorteile gegenüber der in Python integrierten set-Implementierung sind ihr schneller Lookup-Mechanismus (Dank an den zugrunde liegenden BTree) und ihre Persistenzunterstützung.

Hier einige Beispiel-Code ist:

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

Eigentlich funktioniert 'IITreeSet' nur mit Integer-Elementen ... –

1

Vorwärts alle Attribute Anfragen an den internen Satz:

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

Ihre Lösung funktioniert auch, aber ich habe ein paar Änderungen. Ich fügte dem Konstruktor * args hinzu und fügte am Ende des try-Blocks self._p_changed = 1 hinzu ... Ich bin mir nicht sicher, ob das unnötig ist oder ob es versehentlich in der Antwort weggelassen wurde. Vielen Dank. –

+0

@Nikhil, es ist eine einfache Abkürzung. Sie werden nur annehmen, dass jeder variable Zugriff die Daten ändert. Wenn Sie wollen, dass es perfekt ist, wickeln Sie einfach jede Methode, die die Menge mit self ändert._p_changed = 1 – Unknown

1

Für zukünftige Lesungen, ich wollte nur eine leichte Verbesserung gegenüber den bereits vorgeschlagenen Antworten bieten ...

Benutzerdefinierte persistent Setklasse

class PersistentSet(Persistent): 

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

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

Persistent-Set-Klasse aus der Bibliothek

from BTrees.OOBTree import OOSet 

Siehe