我目前正在尝试使用ZCA,但我遇到了一些麻烦。下面的脚本定义了一个IFuncttion
接口,用于创建可链接的函数对象(即monad)。
在此示例中,我尝试创建一个简单的编写器monad作为适配器,但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, [])
答案 0 :(得分: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
参数。