PersistentSet в ZODB 3 - PullRequest
       21

PersistentSet в ZODB 3

3 голосов
/ 18 мая 2009

ZODB предоставляет PersistentList и PersistentMapping, но я бы хотел PersistentSet. Я написал быстрый класс, который отражает древние PersistentList из ZODB 2. Поскольку в Python нет UserSet, мне пришлось расширяться от встроенного в 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 и выбросить все value s.

Ответы [ 3 ]

3 голосов
/ 11 ноября 2009

Почему бы вам не использовать класс постоянного набора, предоставляемый с библиотеками BTree в ZODB. Доступно 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 голос
/ 26 декабря 2014

Для будущих чтений я просто хотел предложить небольшое улучшение по сравнению с уже предложенными ответами ...

Пользовательский постоянный набор классов

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

См. Также

1 голос
/ 18 мая 2009

Пересылать все запросы атрибутов во внутренний набор:

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