适配协议
让我们来更明确地看一下 protocol.adapt() 函数都做了什么事情。在我们的例子中,我们使用“声明 API(declaration API)”来隐式地为适配设置了一组“工厂(factories)”。这个 API 有几个层次。声明 API 的“基本层次(primitives)”是函数: declareAdaptorForType() 、 declareAdaptorForObject() 和 declareAdaptorForProtocol() 。前面的例子中没有用到这些,而是用到了一些高层次的 API,如 declareImplementation() 、 declareAdaptor() 、 adviceObject() 和 protocolForType() 。在一种情况下,我们看到在一个类体中有“奇妙”的 advise() 声明。 advise() 函数支持用于配置那些建议的类的目的和角色的大量关键字参数。您还可以建议 (advise()) 一个模块对象。
您不需要使用声明 API 来创建知道如何使对象适配( adapt() )自己的可适配的对象或者接口。让我们来看 adapt() 的调用标记,然后解释它随后的过程。对 adapt() 的调用类似这样:
adapt() 的调用标记 adapt(component, protocol, [, default [, factory]])
这就表示您希望让对象 component 去适配接口 protocol 。如果指定了 default ,它可以返回为一个包装对象(wrapper object)或者对 component 的修改。如果 factory 被指定为一个关键字参数,那么会使用一个转换工厂来生成包装或者修改。不过让我们先退回一点,来看一下 adapt() 尝试的完整的动作次序(简化的代码):
adapt() 的假想实现 if isinstance(component, protocol): return component elif hasattr(component,'__conform__'): return component.__conform__(protocol) elif hasattr(protocol,'__adapt__'): return protocol.__adapt__(component) elif default is not None: return default elif factory is not None: return factory(component, protocol) else: NotImplementedError
对 adapt() 的调用 应该保持一些特性(不过这是对程序员的建议,而不是库的一般强制要求)。对 adapt() 的调用应该是等幂的。也就是说,对于一个对象 x 和一个协议 P ,我们希望: adapt(x,P)==adapt(adapt(x,P),P) 。高级地,这样做的目的类似于从 .__iter__() 方法返回自身( self )的迭代器(iterator)类的目的。您基本上不会希望去重新适配到您已经适配到的相同类型以产生波动的结果。
(编辑:aniston)
|