__getitem__
__contains__
当没有或__iter__
方法可用时用作后备。请参阅表达式参考文档的成员资格测试操作部分:
最后,尝试了旧式迭代协议:如果一个类定义了__getitem__()
,当且x in y
仅True
当存在一个非负整数索引i满足x is y[i] or x == y[i]
,并且没有更低的整数索引引发IndexError
异常时。
所以实际发生的是 Python 只是使用一个递增的索引,在 Python 中它看起来像这样:
from itertools import count
def contains_via_getitem(container, value):
for i in count(): # increments indefinitely
try:
item = container[i]
if value is item or value == item:
return True
except IndexError:
return False
这种处理扩展到所有迭代功能。未实现__iter__
但已实现的容器__getitem__
仍然可以为它们创建一个迭代器(使用iter()
或 C-API 等效项):
>>> class Container:
... def __init__(self):
... self._items = ["foo", "bar", "baz"]
... def __getitem__(self, index):
... return self._items[index]
...
>>> c = Container()
>>> iter(c)
<iterator object at 0x1101596a0>
>>> list(iter(c))
['foo', 'bar', 'baz']
当然,通过迭代进行的遏制测试并不是很有效。如果有一种方法可以在没有完全扫描的情况下确定容器中的某个项目,请实现一种__contains__
方法来提供更好的实现!
对于卡片组,我可以想象True
当项目是一个Card
实例时简单地返回就足够了(假设Card
该类验证了等级和花色参数):
def __contains__(self, item):
# a card deck contains all possible cards
return isinstance(item, Card)