ZODB 提供了 PersistentList 和一个 PersistentMapping, ,但我想要一个 PersistentSet. 。我写了一个反映古代的快速课程 PersistentList 来自 ZODB 2。因为没有 UserSet 在Python中,我必须从基于C的内置扩展 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

该代码产生了“多个基地有实例布局冲突” 错误. 。我尝试创建一个 UserSet 包装纸 set, ,但这也没有解决问题。

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

最后我导入了 sets.Set (被内置的 set),但这似乎也是用 C 实现的。我在 PyPI 上没有找到任何设置的实现,所以我现在陷入了死胡同。

我有什么选择? 我可能必须从头开始实现一组或使用 UserDict 并扔掉所有的 values。

有帮助吗?

解决方案

你为什么不使用提供的持久化类集合B树中ZODB 的库。有4个可用这样的类。 IITreeSet和IOTreeSet管理组和OITreeSet和OOTreeSet管理已设置任意对象的整数。它们分别对应四个B树类IIBTree,IOBTree,分别OIBTree和OOBTree。他们在内置的Python集合实现优势是其快速查找机制(感谢名单到底层B树)和其持久性的支持。

下面是一些示例代码:

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

其他提示

转发所有属性请求到内部组:

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

对于未来的阅读,我只是想对已经提出的答案稍作改进......

自定义持久集类

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

也可以看看

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top