Gau*_*aut 5 python dictionary iterator
class Test(object):
def __init__(self, store):
assert isinstance(store, dict)
self.store = store
def __getitem__(self, key):
return self.store[key]
Run Code Online (Sandbox Code Playgroud)
我试着在这堂课上喋喋不休.在本文档中 说,实现__getitem__应该足以让我的Test类.实际上,当我试图通过它时,它并没有告诉我我不能,但我有一个KeyError:
In [10]: a = Test({1:1,2:2})
In [11]: for i in a: print i
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-11-8c9c9a8afa41> in <module>()
----> 1 for i in a: print i
<ipython-input-9-17212ae08f42> in __getitem__(self, key)
4 self.store = store
5 def __getitem__(self, key):
----> 6 return self.store[key]
7
KeyError: 0
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过添加__iter__函数来解决它:
def __iter__(self):
return dict.__iter__(self.store)
Run Code Online (Sandbox Code Playgroud)
您错过了您找到的文档中的关键措辞:
对于序列类型,接受的键应该是整数和切片对象.[...] [I] f应该引出序列索引集之外的值(在负值的任何特殊解释之后)
IndexError.注意:
for循环期望IndexError为非法索引引发一个,以允许正确检测序列的结尾.
大胆的斜体重点是我的.如果您接受键而不是整数,则表示您没有序列.
一个可迭代的,它通过
__getitem__()特殊方法使用整数索引支持有效的元素访问,并定义一个__len__()返回序列长度的方法.[...]注意,它dict也支持__getitem__()和__len__(),但是被认为是映射而不是序列,因为查找使用任意不可变键而不是整数.
所以序列接受整数索引,这正是for迭代*时提供的.当给定一个迭代的对象时,如果没有其他方法__getitem__可用,那么构造一个特殊的迭代器,从而开始0并持续增加计数器直到IndexError被引发.在纯Python中,它将是:
def getitem_iterator(obj):
getitem = type(obj).__getitem__ # special method, so on the type
index = 0
try:
while True:
yield getitem(obj, index)
index += 1
except IndexError:
# iteration complete
return
Run Code Online (Sandbox Code Playgroud)
实际的实现是在C中,参见PySeqIter_Type定义和函数.
改为实施该__iter__方法 ; 它存在时使用.由于你包装了一个字典,你可以简单地返回该字典的迭代器(使用iter()函数而不是直接调用特殊方法):
def __iter__(self):
return iter(self.store)
Run Code Online (Sandbox Code Playgroud)
*从技术上讲,for不提供此功能.for只是使用iter(obj)而且当没有方法可用时,它就是产生特殊迭代器的调用__iter__.
| 归档时间: |
|
| 查看次数: |
318 次 |
| 最近记录: |