Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 10, 2013 10:18:30

Юрчек
От:
Зарегистрирован: 2009-04-14
Сообщения: 45
Репутация: +  0  -
Профиль   Отправить e-mail  

интерфейсы и адаптеры

Потихоньку проникаюсь модульной архитектурой twisted Читал http://twistedmatrix.com/documents/12.0.0/core/howto/components.html
И там где-то вскользь упоминается, что интерфейс по запросу необязательно будет возвращать новую копию адаптера. А вот как это реализовать?
Заготовочка кода. Мне хочется связать экземпляр s со своим адаптером, так чтобы sa и sb были ссылками на один и тот же объект.

from twisted.python import components
from zope.interface import Interface, implements
class Service(object):
    pass
class IService(Interface):
    pass
class ServiceAdapter(object):
    implements(IService)
    def __init__(self, service):
        self.service = service
components.registerAdapter(ServiceAdapter, Service, IService)
s = Service()
sa = IService(s)
sb = IService(s)
print sa, sb



Офлайн

#2 Янв. 14, 2013 06:02:04

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

интерфейсы и адаптеры

Читайте `zope.component` и `zope.interface` это интересно ;-). И ещё `zope.annotation` может пригодиться. Посмотрите последний пакет, в купе с `zope.interface.classImplements(Service, zope.annotation.IAttributeAnnotatable)`, если `Service` не ваш.

Ещё можно запилить `ServiceAdapter.__new__` с `weakref` ссылкой (или без :-) на `Service()`. Так же, адаптер не обязан быть классом, это может быть любая функция или метод. Можете создать функцию (ниже пара примеров), которая по неким атрибутам либо создаёт, либо возвращает созданный экземпляр `ServiceAdapter`. То же самое можно проделать с методом класса, что бы не гадить в глобальном пространстве:

# ...
@zope.component.adapter(Service)
@zope.interface.implementer(IService)
def myadapter(svc):
    if not svc in myglobaldict:
        myglobaldict[svc] = ServiceAdapter(svc)
    return myglobaldict[svc]
#twisted.python.components.registerAdapter(myadapter, Service)
# или
#zope.component.provideAdapter(myadapter)
# а лучше
zope.component.getSiteManager()\
    .registerAdapter(myadapter)
# ...

# ...
class ServiceAdapterProvider(object):
    def __init__(self):
        self.mydict = {}
        twisted.python.components.registerAdapter(self.adapter, Service, IService)
    def adapter(self, svc):
        if not svc in self.mydict:
            self.mydict[svc] = ServiceAdapter(svc)
        return self.mydict[svc]
# ...

В общем суть одна, реализаций может быть сколь угодно.
ZCA это не изобретение Twisted, так что пользуйтесь первоисточниками, ну и посматривайте, чего там в `twisted.python.components` начудили.

Да, забыл самое главное сказать, исходники открыты и их можно почитать, если возникают вопросы :-).

..bw



Отредактировано bw (Янв. 14, 2013 06:09:52)

Офлайн

#3 Янв. 14, 2013 15:05:11

Юрчек
От:
Зарегистрирован: 2009-04-14
Сообщения: 45
Репутация: +  0  -
Профиль   Отправить e-mail  

интерфейсы и адаптеры

Спасибо. Фабрика ServiceAdapterProvider - это то что надо, вроде ничего сложного, проверять через словарик, а не был ли создан адаптер ранее, но вот я не догадался))



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version