3.3.5 模拟包容器类型 Emulating container types

The following methods can be defined to implement container objects. Containers usually are sequences (such as lists or tuples) or mappings (like dictionaries), but can represent other containers as well. The first set of methods is used either to emulate a sequence or to emulate a mapping; the difference is that for a sequence, the allowable keys should be the integers k for which 0 <= k < N where N is the length of the sequence, or slice objects, which define a range of items. (For backwards compatibility, the method __getslice__() (see below) can also be defined to handle simple, but not extended slices.) It is also recommended that mappings provide the methods keys(), values(), items(), has_key(), get(), clear(), setdefault(), iterkeys(), itervalues(), iteritems(), pop(), popitem(), copy(), and update() behaving similar to those for Python's standard dictionary objects. The UserDict module provides a DictMixin class to help create those methods from a base set of __getitem__(), __setitem__(), __delitem__(), and keys(). Mutable sequences should provide methods append(), count(), index(), extend(), insert(), pop(), remove(), reverse() and sort(), like Python standard list objects. Finally, sequence types should implement addition (meaning concatenation) and multiplication (meaning repetition) by defining the methods __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() and __imul__() described below; they should not define __coerce__() or other numerical operators. It is recommended that both mappings and sequences implement the __contains__() method to allow efficient use of the in operator; for mappings, in should be equivalent of has_key(); for sequences, it should search through the values. It is further recommended that both mappings and sequences implement the __iter__() method to allow efficient iteration through the container; for mappings, __iter__() should be the same as iterkeys(); for sequences, it should iterate through the values.

定义以下方法可以实现包容器对象.包容器通常指有序类型(像列表或元组)或映射(像字典), 但也可以表示其它包容器. 第一个方法集用于模拟有序类型或映射; 有序类型的区别就在于, 允许键可以是整数k, 其中0 <= K < N, N是有序类型的长度, 或者是描述了一定范围的片断(出于向后兼容性的考虑, __getslice__()方法可能用于控制简单的片断, 但不能用于扩展的片断句法). 在实现映射时, 推荐提供keys(), values(), items(), has_key(), get(), clear(), copy(), 和 update(), 使其行为类似于Python标准的字典对象; 可变的有序类型应该提供方法append(), count(), index(), insert(), pop(), remove(), reverse() 和 sort(),就像Python标准的列表类型. 最后, 有序类型应该通过定义下述的方法__add__(), __radd__(), __iadd__(), __mul__(), __rmul__() 和__imul__()实现加法运算(就是指连接)和乘法运算(指重复).它们不应该定义__coerce__() 或其它数值运算操作.对于有序类型和字典都推荐实现__contains__(), 以便于高效的使用in运算符.对于它应该等价于has_key()方法,对于有序类型,通过值进行搜索. 

__len__( self)
Called to implement the built-in function len(). Should return the length of the object, an integer >= 0. Also, an object that doesn't define a __nonzero__() method and whose __len__() method returns zero is considered to be false in a Boolean context.

实现内建函数len()相仿的功能, 应该返回对象的长度,并且返回一个大于等于0的整数, 另外,一个没有定义__nonzero__()的方法返回0被认为是返回一个逻辑假值.

__getitem__( self, key)
Called to implement evaluation of self[key]. For sequence types, the accepted keys should be integers and slice objects. Note that the special interpretation of negative indexes (if the class wishes to emulate a sequence type) is up to the __getitem__() method. If key is of an inappropriate type, TypeError may be raised; if of a value outside the set of indexes for the sequence (after any special interpretation of negative values), IndexError should be raised. Note: for loops expect that an IndexError will be raised for illegal indexes to allow proper detection of the end of the sequence.

实现self[key]相仿的功能.对于有序类型,可接受的键包括整数和片断对象.注意对负数索引(如果类希望模拟有序类型)的特殊解释也依赖于__getitem__()方法.如果键是不合适的类型,一个TypeError异常就会被抛出,如果某个值在有序类型的索引值集合之外(在任何负值索引的特定解释也不能行的通的情况下),会抛出一个IndexError的异常.注意:for循环可以通过对由于对无效索引值而抛出的IndexError异常进行捕获来对访问有序类型的结尾做适当地检测.

__setitem__( self, key, value)
Called to implement assignment to self[key]. Same note as for __getitem__(). This should only be implemented for mappings if the objects support changes to the values for keys, or if new keys can be added, or for sequences if elements can be replaced. The same exceptions should be raised for improper key values as for the __getitem__() method.

在对self[key]进行赋值时调用.与__getitem__()有着相同的注意事项.通常只对映射实现本方法, 并且要求对象支持改变键所对应的值,或支持增加新键;也可以在有序类型中实现,此时支持单元可以替换.在使用无效的键值时, 会抛出与__getitem__()相同的异常.

__delitem__( self, key)
Called to implement deletion of self[key]. Same note as for __getitem__(). This should only be implemented for mappings if the objects support removal of keys, or for sequences if elements can be removed from the sequence. The same exceptions should be raised for improper key values as for the __getitem__() method.

在删除self[key]时调用,与__getitem__()有着相同的对象.本方法通常仅仅在映射中实现,并且对象支持键的删除;也可以在有序类型中实现,此时单元可以从有序类型删除.在使用无效的键值时, 会抛出与__getitem__()相同的异常.

__iter__( self)
This method is called when an iterator is required for a container. This method should return a new iterator object that can iterate over all the objects in the container. For mappings, it should iterate over the keys of the container, and should also be made available as the method iterkeys().

要求使用包容器的迭代子时,这个方法被调用.本方法应该返回一个可以迭代包容器所有对象的迭代子对象.对于映射,应该在键的基础上进行迭代,并且也应该像方法iterkeys()一样有效.

Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see ``Iterator Types'' in the Python Library Reference.

迭代子对象也需要实现这个方法,它们应该返回它自己.对于更多的关于迭代子对象的信息, 参见 Python 库参考 中的 Iterator Types.

The membership test operators (in and not in) are normally implemented as an iteration through a sequence. However, container objects can supply the following special method with a more efficient implementation, which also does not require the object be a sequence.

成员测试运算符(in和not in)一般通过对有序类型的迭代来实现.但是包容器也可以提供以下方法得到更有效的实现,不要对象是有序类型.

__contains__( self, item)
Called to implement membership test operators. Should return true if item is in self, false otherwise. For mapping objects, this should consider the keys of the mapping rather than the values or the key-item pairs.

使用成员测试运算符时调用.如果item在self中, 返回true; 否则返回false. 对于映射对象,比较应该在键上进行,不应该是键值对.