0

我目前正在尝试使用 ZCA,但遇到了一些麻烦。下面的脚本定义了一个IFuncttion接口,用于创建可以链接的函数对象(即monads)。

在此示例中,我试图创建一个简单的 writer 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, [])
4

1 回答 1

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传入的额外参数。

于 2015-02-22T02:00:17.467 回答