2015-02-21 3 views
0

В настоящее время я экспериментирую с ZCA, и я столкнулся с проблемой заминки. В приведенном ниже сценарии указан интерфейс IFuncttion, который используется для создания объектов функций, которые могут быть закодированы (например, монады).Почему мой MultiAdapter не регистрируется?

В этом примере я пытаюсь создать простую монаду-писатель в качестве адаптера, но 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 аргумент принят.

Смежные вопросы