Ошибка при попытке зарегистрировать реализатор 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,))
Конечно, этот пример выше представляет собой адаптер, который претендует на адаптацию к любому контексту, что не рекомендуется, если вы не знаете, зачем вам это нужно.