改变大小信息
难易程度: 初学者
技能要求:
您应该熟悉“内容组件”一章。
问题/任务:
现在,当然我们查看消息内容视图时,它将在消息里显示条目的数目,它包括回复消息和附件(文件和图像)。如果大小字段以“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(显示大小)。