改变大小信息 难易程度: 初学者 技能要求: 您应该熟悉“内容组件”一章。 问题/任务: 现在,当然我们查看消息内容视图时,它将在消息里显示条目的数目,它包括回复消息和附件(文件和图像)。如果大小字段以“x- 回复, y- 附件”显示是一个不错的主意。 解决方案: 一个非常简单的适配器来处理大小输出,该适配器ISized将由IMessage修改而成。 第I步: 适配器的实现 一个适配器通常是一个简单的类, 它把一个对象当作一个构造函数参数。这个类必须提供"from" 接口,该接口也经常在该类 __used_for__ 属性中被列出。在您的message.py文件中添加如下代码: ISized接口指定了两个方法: 第10-12行:sizeForString() 必须以第一个元素是单位(unit)和第二个是值(value)返回一个元组。选择提供一个通用的大小表示比较的格式。 第14-19行:sizeForDisplay() 能返回表示该对象尺寸任何种类的unicode字符串。 输出不应该太长(我的已经很长)。正如我们承诺的分开显示回复和附件。 第II步: 单元测试 现在让我们为适配器写一些doc测试。 把下列的测试代码加入到sizeForSorting() 的doc字符串方法: >> size = MessageSized(Message()) 4 5 Here are some examples of the expected output. 6 7 >>> size.sizeForSorting() 8 ('item', 0) 9 >>> size._message['msg1'] = Message() 10 >>> size.sizeForSorting() 11 ('item', 1) 12 >>> size._message['att1'] = object() 13 >>> size.sizeForSorting() 14 ('item', 2) ]]> 由于我们添加了一个对象并且检查项目的大小是否增加。在sizeForDisplay() doc字符串添加: >> size = MessageSized(Message()) 4 5 Here are some examples of the expected output. 6 7 >>> size.sizeForDisplay() 8 u'0 replies, 0 attachments' 9 >>> size._message['msg1'] = Message() 10 >>> size.sizeForDisplay() 11 u'1 reply, 0 attachments' 12 >>> size._message['msg2'] = Message() 13 >>> size.sizeForDisplay() 14 u'2 replies, 0 attachments' 15 >>> size._message['att1'] = object() 16 >>> size.sizeForDisplay() 17 u'2 replies, 1 attachment' 18 >>> size._message['att2'] = object() 19 >>> size.sizeForDisplay() 20 u'2 replies, 2 attachments' ]]> doc测试已经被注册,由于message.py文件已经包含了一些doc测试。然而,把一个对象加入一个容器需要一些结构组件运行在上面。这儿有一个叫zope.app.tests.placelesssetup便利的测试模块,它包含了能以位置参数传递到doc测试套件的两个函数:setUp()和tearDown()。因此,这些测试套件声明需要做些改变: 变成 您现在可以用通常的方式运行测试: 第III步: 注册 现在我们使用下面的ZCML指令在messageboard/configure.zcml中注册适配器: ]]> zope:adapter是通过ZCML注册全局适配器的方法。工厂(factory)属性允许您指定一连串的工厂(通常只有一个被指定),专门负责创建适配器实例。在for属性里指定对象实现的接口,在provides里指定提供的接口。所有这三个属性都是强制性的。 对于我们的范例,我们基本上说 MessageSized 类的实例提供一个 ISized 接口给实现 IMessage 的对象。 指令也支持两个可选择的参数。我们也能指定一个许可。如果主体已经指定了许可,适配器将只对主体可用。如果没有许可指定,每个人都能访问该适配器。指令的其它可选参数是name属性,该属性指定了适配器的名称。使用名称,我们能从一个接口到另一个接口指定多个适配器。 这就是本章所有的内容了。重新启动Zope 3 并且自个儿瞧瞧。 注意我们不需要接触任何已经存在的Python代码就可以提供这些功能了。 练习 为 IMessageBoard 写一个 ISized 适配器输出xmessages(显示大小)。