Уведомления

Группа в Telegram: @pythonsu

#1 Май 13, 2011 13:40:18

Cykooz
От:
Зарегистрирован: 2010-10-07
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

BB: Какие есть варианты реализации ссылки на объект?

Требуется реализовать поле в объекте, которое будет хранить ссылку на другой объект в ZODB.
Самая первая пришедшая на ум реализация - хранить id объекта возвращаемый утилитой IIntIds.
После этого стал копать PyPi на предмет готовых компонентов. Нашёл только один более или менее подходящий пакет - gocept.reference. Все остальные найденые реализации довольно старые и не подходят для ZTK 1.1 без работы напильником.
К сожалению gocept.reference имеет, как мне кажется, небольшой недостаток - в качестве ссылки на объект он использует путь к нему от корня ZODB. Следовательно для получения объекта требуется выполнить полный траверс этого пути. По моему это не очень оптимальный вариант. Каких либо плюсов такого подхода я не вижу.

Может кому то уже приходилось делать, что то подобное? Как лучше это сделать?



Офлайн

#2 Май 13, 2011 14:15:38

Sleepwalker
От:
Зарегистрирован: 2008-07-18
Сообщения: 68
Репутация: +  0  -
Профиль   Отправить e-mail  

BB: Какие есть варианты реализации ссылки на объект?

Есть продукт z3c.relationfield. Чесно говоря не использовал его, но по описанию очень Вам подходит. Он завязан на IntIds.

Еще один вариан - использовать перзистентные WeakRef - http://docs.zope.org/zope3/Code/persistent/wref/WeakRef
Тогда и IntId не нужна. Этот вариант мне как-то больше по душе.



Офлайн

#3 Май 13, 2011 15:03:03

Cykooz
От:
Зарегистрирован: 2010-10-07
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

BB: Какие есть варианты реализации ссылки на объект?

Sleepwalker
Есть продукт z3c.relationfield. Чесно говоря не использовал его, но по описанию очень Вам подходит. Он завязан на IntIds.
Да, он вероятно подошёл бы, но только он настолько старый что зависимости у него не очень хорошие (тот же IntIds берётся например из zope.app.intids).

Пока что начал использовать gocept.reference, там в принципе при желании можно переопределить класс Reference и использоувать свой метод для получения ключа к объекту.

А использование WeakRef, насколько я понял, может привести к проблемам, т.к. такая ссылка ссылается на конкретную версию объекта и при изменении объекта или его удалении будет по прежнему ссылаться на старую версию. Вот что по этому поводу написанно в доке к gocept.reference:
Weak references.
The reference might have become stale and leave the referencing object in an invalid state.



Офлайн

#4 Май 13, 2011 15:35:49

Sleepwalker
От:
Зарегистрирован: 2008-07-18
Сообщения: 68
Репутация: +  0  -
Профиль   Отправить e-mail  

BB: Какие есть варианты реализации ссылки на объект?

Ну да, поэтому и в примере с weakref что я кидал, база пакуется после удаления обьекта …



Офлайн

#5 Май 13, 2011 15:38:51

Cykooz
От:
Зарегистрирован: 2010-10-07
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

BB: Какие есть варианты реализации ссылки на объект?

Подумав немного я понял, что вариант с IntIds не подходит, т.к. в моём случае важно не то на какой конкретно объект указывает ссылка, а на то где он находится в иерархии. В случае использования IntIds я могу переместить объект совершено в другое место и ссылка по прежнему будет указывать на него.



Офлайн

#6 Май 13, 2011 15:43:23

astoon
От:
Зарегистрирован: 2007-04-09
Сообщения: 335
Репутация: +  2  -
Профиль   Отправить e-mail  

BB: Какие есть варианты реализации ссылки на объект?

Наоборот weak reference решает проблемы, не?

Порассуждаю чуток.

В ZODB стопицот способов сделать отношения между объектами. Точнее - столько же, сколько есть в самом Python.

Соответственно, в кажом проекте используется много разных, наверняка, и в разных сочетаниях. Это нормально и это на каждом шагу. Например, самый распостраненный сопсобо - это протокол ILocation, и его персистемное воплощение IConainer / IContained.

Не забывайте, что если мы просто кладем объект в атрибуты несокльких другох объектов, то это не будет дублирование, это будет один объект. Т.е. ZODB это суть ваш пайтон код. Соответственно, это и есть самый правильный способ работать с ZODB, потому что надо получать преимущества от его использования в виде минимизации кода и сущностей в коде. А иначе зачем тогда вообзе использовать ZODB.

На месте же уже решать, класть сам объект, или его ID, или waek reference. Правда состоит в том, что на практике во всех случаях все равно нужно отслеживать удаление исходного объекта и предпринимать в связи с этим какие-то действия. Ну, на то есть события и подписчики.

Второй вопрос - чтобы виджеты изкоробки сразу работали по схеме. Например, если это Choice то задача сводится к тому, чтобы сделать корректный vocabulary, где title - это отображаемая строка, token и term - то, что сохраняем в (и берем из). Достоверно скажу лишь что это работает так, как и ожидается, испробовано много раз.



Офлайн

#7 Май 13, 2011 15:47:24

astoon
От:
Зарегистрирован: 2007-04-09
Сообщения: 335
Репутация: +  2  -
Профиль   Отправить e-mail  

BB: Какие есть варианты реализации ссылки на объект?

кроме intids / weak reference / reference лично я часто испорльзую __name__ объекта (или просто его числовой ключ, если он в IOBTree, атрибуте, а не в IContainer). В этих случаях известно, что объекты, на которые ссылаемся, лежат в определенном известном месте, так что не проблема взять их по __name__ или некоторому другому ключу.

А какое конкретно решение выбирать, тут уж каждый раз смотреть.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version