Now we are finally ready to implement the content components of the package. This is the heart of this chapter. But how do we know which methods and properties we have to implement? There is a neat tool called pyskel.py in ZOPE3/utiltities that generates a skeleton. Go to ZOPE3/src and type:

现在,我们终于准备好要实现这个软件包的内容组件了。这是本章节的核心部分。但是我们如何知道我们应当诠释哪些方法和属性呢? 在ZOPE3/utilites中有一个名为pyskel.py的好工具,它能够生成一个框架。进入ZOPE3/src,然后键入:

1 python2.3 ../utilities/pyskel.py \ 2 book.messageboard.interfaces.IMessageBoard

The expected result is shown below. The tool inspects the given interface and creates the skeleton of an implementing class. It also recurses into all base interfaces to get their methods. Here the generated code:

预计的输出结果显示如下。该工具检查给定的接口并创建该接口的实现类的框架。它还会递归进入所有基础接口,并获取他们的方法。以下是生成的代码:

10 def setitem(self, name, object): 11 "See book.messageboard.interfaces.IMessageBoard" 12 13 # See book.messageboard.interfaces.IMessageBoard 14 description = None 15 16 def getitem(self, key): 17 "See zope.interface.common.mapping.IItemMapping" 18 19 def get(self, key, default=None): 20 "See zope.interface.common.mapping.IReadMapping" 21 22 def contains(self, key): 23 "See zope.interface.common.mapping.IReadMapping" 24 25 def getitem(self, key): 26 "See zope.interface.common.mapping.IItemMapping" 27 28 def keys(self): 29 "See zope.interface.common.mapping.IEnumerableMapping" 30 31 def iter(self): 32 "See zope.interface.common.mapping.IEnumerableMapping" 33 34 def values(self): 35 "See zope.interface.common.mapping.IEnumerableMapping" 36 37 def items(self): 38 "See zope.interface.common.mapping.IEnumerableMapping" 39 40 def len(self): 41 "See zope.interface.common.mapping.IEnumerableMapping" 42 43 def get(self, key, default=None): 44 "See zope.interface.common.mapping.IReadMapping" 45 46 def contains(self, key): 47 "See zope.interface.common.mapping.IReadMapping" 48 49 def getitem(self, key): 50 "See zope.interface.common.mapping.IItemMapping" 51 52 def setitem(self, name, object): 53 "See zope.app.container.interfaces.IWriteContainer" 54 55 def delitem(self, name): 56 "See zope.app.container.interfaces.IWriteContainer"

This result is good but some parts are unnecessary; we will for example simply inherit the BTreeContainer base component, so that we do not have to implement the methods from the IReadMapping, IEnumerableMapping, IReadMapping, IItemMapping and IWriteContainer interfaces.

该结果已经非常好了,不过还需要另外一些部分;例如我们需要简单的基础BTreeContainer基础组件,这样我们就不需要来自IReadMapping、IEnumberableMapping、IReadMapping、IItemMapping和 IWriteContainer接口中的方法。

Open a new file called messageboard.py for editing. The implementation of the message board including doc tests looks like this:

打开一个名为messageboard.py的新文件进行编辑。包含文档测试件的message board的实现如下所示:

10 interface: 11 12 >>> from zope.interface.verify import verifyClass 13 >>> verifyClass(IMessageBoard, MessageBoard) 14 True 15 16 Here is an example of changing the description of the board: 17 18 >>> board = MessageBoard() 19 >>> board.description 20 u 21 >>> board.description = u'Message Board Description' 22 >>> board.description 23 u'Message Board Description' 24 """ 25 implements(IMessageBoard) 26 27 # See book.messageboard.interfaces.IMessageBoard 28 description = u

· On line 12-14 we verify that the MessageBoard component really implements IMessageBoard. The verifyClass function actually checks the object for the existence of the specified attributes and methods.

· 第12-14行,我们验证该MessageBoard组件确实实现的是IMessageBoard. 这个验证函数会对该对象存在的指定属性和方法进行实际的检查。

Lines 18 through 23 just give a demonstration about the default description value and how it can be set. The test seems trivial, but at some point you might change the implementation of the description attribute to using properties and the test should still pass.

Note: Python is very unique in this way. In almost any other object-oriented language (for example Java) one would have written an accessor ( getDescription()) and a mutator ( setDescription(desc)) method. However, Python’s attribute and property support makes this unnecessary, which in turn makes the code cleaner.

The next task is to write the Message object, which is pretty much the same code. Therefore we will not list it here and refer you to the code at http://svn.zope.org/book/trunk/messageboard/step01/message.py. The only difference is that in this case the Message component must implement IMessage, IMessageContained, and IMessageContainer.

Zope3Book/ch13.5 (last edited 2009-12-25 07:15:06 by localhost)