Вопрос

ZODB предоставляет PersistentList и PersistentMapping, но мне бы хотелось PersistentSet.Я написал быстрый урок, который отражает древний PersistentList из ЗОДБ 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 и выбросить все valueс.

Это было полезно?

Решение

Почему бы вам не использовать класс постоянного набора, поставляемый с БТри библиотеки в ZODB.Всего доступно 4 таких класса.IITreeSet и IOTreeSet управляют наборами целых чисел, а OITreeSet и OOTreeSet управляют набором произвольных объектов.Они соответствуют четырем классам BTree: IIBTree, IOBTree, OIBTree и OOBTree соответственно.Их преимущества перед реализацией set, встроенной в 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])

Другие советы

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

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