2009-05-17 58 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