2009-05-17 27 views
3

ZODB提供了一個PersistentListPersistentMapping,但我想要一個PersistentSet。我寫了一個快速課,反映了ZODB 2中的古代PersistentList。由於Python中沒有UserSet,我不得不從基於C的內置set擴展。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 

該代碼產生了「多個基地有實例佈局衝突」error。我試着在set周圍創建一個UserSet包裝,但是這也沒有解決問題。

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

最後,我進口sets.Set(由內置set取代),但似乎在C中實現了。我沒有在PyPI上找到任何設置實現,所以我現在處於死衚衕。

我有什麼選擇?我可能必須從零開始實施一套或使用UserDict並扔掉所有value s。

回答

3

你爲什麼不使用提供與ZODB的BTree庫持久集合類。有4個這樣的類可用。 IITreeSet和IOTreeSet管理整數集合,OITreeSet和OOTreeSet管理任意對象的集合。它們分別對應於四個BTree類IIBTree,IOBTree,OIBTree和OOBTree。它們比Python內置的實現更有優勢,它們具有快速查找機制(比基礎BTree更好)以及持久性支持。

下面是一些示例代碼:

>>> 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]) 
1

轉發所有屬性請求到內部設置:

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

您的解決方案的工作原理看,但我做了一些改動。我在構造函數中添加了* args,並且在try塊的末尾添加了self._p_changed = 1 ...我不確定這是否不必要,或者是否在響應中被意外省略。謝謝。 – 2009-05-18 21:23:12

+0

@Nikhil,這是一個簡單的捷徑。您只會假設每個變量訪問都會更改數據。如果你希望它是完美的,只需要包裝每一個改變集合的方法。_p_changed = 1 – Unknown 2009-05-18 21:48:23

1

對於未來的讀數,我只是想提供在已經提出的答案稍有好轉...

自定義持久集類

class PersistentSet(Persistent): 

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

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

庫中的持久集合類

from BTrees.OOBTree import OOSet