Почему мой MultiAdapter не может зарегистрироваться?
В настоящее время я экспериментирую с ZCA, и я столкнулся с небольшой заминкой. Сценарий ниже определяет IFuncttion
интерфейс, который используется для создания функциональных объектов, которые могут быть связаны (например, монады).
В этом примере я пытаюсь создать простую монаду писателя в качестве адаптера, но getMultiAdapter
поднимает ComponentLookupError
, Почему это?
from zope import component, interface
class IFunction(interface.Interface):
name = interface.Attribute('Name of the function object')
def __call__(*args, **kw):
"""Call the function"""
class Function(object):
name = ''
interface.implements(IFunction)
def __call__(self, *args, **kw):
return self.run(*args, **kw)
def run(self, *args, **kw):
raise NotImplementedError
class MWriter(object):
component.adapts(IFunction, IFunction)
interface.implements(IFunction)
def __init__(self, prv, nxt):
self.prev, self.next = prv, nxt
def bind(self, x, log=None):
log = log or []
result, line = self.prev(x)
log.append(line)
return self.next(result, log)
def __call__(self, *args, **kw):
return self.bind(*args, **kw)
class AddOne(Function):
name = 'addone'
def run(self, x):
return x + 1
class MulTwo(Function):
name = 'multwo'
def run(self, x):
return x * 2
component.provideAdapter(MWriter)
print component.getMultiAdapter((AddOne(), MulTwo()), MWriter)(11, [])
1 ответ
Вы не должны передавать адаптер, на который хотите посмотреть component.getMultiAdapter()
, Второй аргумент этой функции - это имя, используемое для именованных адаптеров, но ваша регистрация не использовала имя.
Просто удалите этот второй аргумент:
>>> component.getMultiAdapter((AddOne(), MulTwo()))
<__main__.MWriter object at 0x1072516d0>
К сожалению звоню MWriter()
по-прежнему не удается, потому что вы ожидаете self.prev()
вернуть кортеж:
result, line = self.prev(x)
но AddOne()
возвращает только одно целое число:
class AddOne(Function):
name = 'addone'
def run(self, x):
return x + 1
так что вы получите исключение:
>>> component.getMultiAdapter((AddOne(), MulTwo()))(11)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 37, in __call__
File "<string>", line 32, in bind
TypeError: 'int' object is not iterable
Возможно, вы хотели друг Function()
вернуть имя и результат:
class Function(object):
name = ''
interface.implements(IFunction)
def __call__(self, *args, **kw):
return self.run(*args, **kw), self.name
def run(self, *args, **kw):
raise NotImplementedError
но потом звоню self.next()
не удается, потому что он не принимает дополнительные log
аргумент передан.