Ответ 1
def __iter__(self): return self.books.itervalues()
У меня есть объект со словарем, к которому я хочу получить доступ через __getitem__
, а также итерацию (только значения, ключи не имеют значения), но я не уверен, как это сделать.
Например:
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
>>>
Как мне сказать, чтобы просто вернуть object
для каждого элемента в словаре (ключ не имеет значения)?
def __iter__(self): return self.books.itervalues()
Добавьте этот метод в библиотеку:
def __iter__(self):
return self.books.itervalues()
Это делегирует итерацию dict, которая имеет простой способ для итерации значений. Читайте об протоколе итератора, который состоит из методов __iter__
(по всем итерам) и next
(__next__
в 3.x) (только для итераторов).
>>> 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'>
Вы можете вернуть итератор из своих внутренних данных:
class Library (object):
...
def __iter__(self):
return self.books.itervalues()
itervalues()
возвращает итератор в значения словаря.
Если вы хотите большего контроля, вы можете сделать __iter__
функцию генератора
class Library (object):
...
def __iter__(self):
for title in self.books:
yield self.books[title]
в этом случае этот генератор дает то же самое, что и итератор в первом примере.
Рассматривали ли вы использование UserDict mixin?
__getitem__(self,key)
, где ключ является целым числом, так как ваш self.books - это словарь, и вы не можете сделать self.books[integer]
например:
>>>d = {'a':'sdsdsd','b':'sfsdsd'}
>>d[0]
d[0]
Traceback (most recent call last):
File "<console>", line 1, in <module>
KeyError: 0
протокол итерации выглядит следующим образом:
Протокол итератора состоит из двух методов. Метод __iter__()
, который должен возвращать объект итератора и метод next()
, который возвращает следующий элемент из последовательности.
ранее, когда метод __iter__
не определялся, он возвращался к __getitem__
, последовательно вызывая __getitem__
с увеличением значений до тех пор, пока не выдаст ошибку индекса за пределами диапазона.