问题
I have an object with a dictionary that I want to access via __getitem__ as well as iterate over (values only, keys don't matter) but am not sure how to do it.
For example:
Python 2.5.2 (r252:60911, Jul 22 2009, 15:33:10)
>>> class Library(object):
... def __init__(self):
... self.books = { 'title' : object, 'title2' : object, 'title3' : object, }
... def __getitem__(self, i):
... return self.books[i]
...
>>> library = Library()
>>> library['title']
<type 'object'>
>>> for book in library:
... print book
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __getitem__
KeyError: 0
>>>
How do I tell it to simply return the object for each item in the dictionary (the key doesn't matter) ?
回答1:
def __iter__(self): return self.books.itervalues()
回答2:
Add this method to Library:
def __iter__(self):
return self.books.itervalues()
This delegates iteration to the dict, which has an easy method to iterate values. Read about the iterator protocol, which consists of __iter__ (on all iterables) and next(__next__ in 3.x) (only on iterators) methods.
回答3:
You can return an iterator from your inner data:
class Library (object):
...
def __iter__(self):
return self.books.itervalues()
itervalues() returns an iterator to the values of the dictionary.
If you want more control, you can make __iter__ a generator function
class Library (object):
...
def __iter__(self):
for title in self.books:
yield self.books[title]
in this case, this generator yields the exact same as the iterator in the first example.
回答4:
>>> class Library(object):
... def __init__(self):
... self.books = { 'title' : object, 'title2' : object, 'title3' : object, }
... def __getitem__(self, i):
... return self.books[i]
... def __iter__(self):
... return self.books.itervalues()
...
>>> library = Library()
>>> library['title']
<type 'object'>
>>> for book in library:
... print book
...
<type 'object'>
<type 'object'>
<type 'object'>
回答5:
__getitem__(self,key), where key is a integer, as your self.books is a dictionary and you can not do self.books[integer]
e.g:
>>>d = {'a':'sdsdsd','b':'sfsdsd'}
>>d[0]
d[0]
Traceback (most recent call last):
File "<console>", line 1, in <module>
KeyError: 0
the iteration protocol goes like this:
The iterator protocol consists of two methods. The __iter__() method, which must return the iterator object and the next() method, which returns the next element from a sequence.
previously when __iter__ method was not defined, it fell back to __getitem__ by successively calling __getitem__ with increasing values till it gives index out of range error.
来源:https://stackoverflow.com/questions/1780571/how-do-i-use-getitem-and-iter-and-return-values-from-a-dictionary