Ошибка при попытке зарегистрировать реализатор zope.interface

У меня следующий класс:

@implementer(ISocial)
class SocialVKSelenium:
    pass

И когда я добавлю его в реестр Zope:

gsm = getGlobalSiteManager()
gsm.registerAdapter(SocialVKSelenium)

Я получил: TypeError: The adapter factory doesn't have a __component_adapts__ attribute and no required specifications were specified

Когда я добавляю туда адаптер (IOther), регистрация работает как положено, а без - нет. Почему это происходит?

1 ответ

Решение

Вам необходимо предоставить контекст либо для класса, либо для реестра.

Я подозреваю, что вы не передаете весь набор проблем - адаптер - это компонент, который адаптирует объект указанного интерфейса и предоставляет другой. В вашем примере не указано, какой контекст адаптируется, то есть какой тип объекта адаптируется при построении объекта адаптера его классом?

Например, это прекрасно работает:

from zope.interface import Interface, implements
from zope.component import getGlobalSiteManager, adapts


class IWeight(Interface):
    pass


class IVolume(Interface):
    pass

class WeightToVolume(object):
    implements(IVolume)
    adapts(IWeight)
    #...


gsm = getGlobalSiteManager()
gsm.registerAdapter(WeightToVolume)

Хотя вы можете использовать для этого синтаксис декоратора (реализатор / адаптер), по соглашению использование агрегатов / адаптеров предпочтительнее для фабрик адаптеров, которые являются классами, а не функциями.

Как минимум, если ваш адаптер не объявляет, что он адаптирует в самой функции класса или фабрики, вам нужно указать реестр. В самом широком случае это может выглядеть так:

gsm.registerAdapter(MyAdapterClassHere, required=(Interface,))

Конечно, этот пример выше представляет собой адаптер, который претендует на адаптацию к любому контексту, что не рекомендуется, если вы не знаете, зачем вам это нужно.

Другие вопросы по тегам