Найти - Пользователи
Полная версия: Протоколы итерации
Начало » Python для новичков » Протоколы итерации
1 2
taxik
terabayt
и вот еще пример
Интересный пример, но здесь у вас возвращается итератор уже встроенного класса list. Вы можете привести пример получения итератора через объект который не содержит __next__? - как у списков и словарей. Т.е. применив __iter__() к такому объекту который не содержит __next__, но его итератор уже будет с этим методом.)
terabayt
taxik
но здесь у вас возвращается итератор уже встроенного класса list
taxik
объекта который не содержит __next__? - как у списков
эмм.. что-то я не понял. list это список!

iter это built-in функция
вот пример
class C:
    def __init__(self, s):
        self.s = s
    def __iter__(self):
        print 'iter!!! ---'
        return iter(self.s)
a = C('hello')
print(dir(a))
print(dir(a.__iter__()))
for c in a:
    print c
taxik
terabayt
эмм.. что-то я не понял. list это список!
это я понимаю.)
terabayt
вот пример
Ваш класс C создает итератор для класса str, вы же в self.s передали строку. Получилась просто объертка.

Давайте попробуем так: в классе list нету метода __next__, но вызывая iter к его объекту, интерпритатор не ругается. Но когда мы делаем свой класс без __next__ и возвращаем в __iter__ self он ругается. Вопрос в том почему же он не ругается когда мы применяем iter к объекту list? Или еще можно так - что же такого делает __iter__ в классе list что __next__ вдруг появляется у итератора, вы же не думаете что там:
return iter([...])
terabayt
taxik
вы же недумаете что там return iter()
а почему бы и нет?!
как сказал py.user.next
py.user.next
Он вызывает iter() для L и использует полученный объект для вызовов next().
iter, как я уже говорил, buil-in функция и я не вижу почему бы for или __iter__ не использовать его?
документация
taxik
terabayt
а почему бы и нет?!
Такого не может быть, потому что получится бесконечная рекурсия. - чтобы получить итератор нужно получить итератор от самого себя…
iter() вызывает __iter__() объекта.
bismigalis
может так будет понятней

>>> type([].__iter__())
<type 'listiterator'>
taxik
bismigalis
может так будет понятней
Спасибо! я прозрел..))) Он просто возвращает объект другого класса который содержит __next__.

И terabayt спасибо за наводки.
py.user.next
taxik
Спасибо, а вы можете дать ссылку где это указано(можно и на англ.)?

https://docs.python.org/3/glossary.html#term-iterable
When using iterables, it is usually not necessary to call iter() or deal with iterator objects yourself. The for statement does that automatically for you, creating a temporary unnamed variable to hold the iterator for the duration of the loop.

Можно проверить, как предлагал terabayt :
>>> class A:
...     def __iter__(self):
...         print('In iter')
...         self.it = iter('abc')
...         return self
...     def __next__(self):
...         print('In next')
...         return next(self.it)
... 
>>> a = A()
>>> for i in a:
...     print(i)
... 
In iter
In next
a
In next
b
In next
c
In next
>>>

Нужно различать итератор и итерэбл:
>>> class A:
...     pass
... 
>>> a = A()
>>> iter(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'A' object is not iterable
>>>

Создание итератора из итерэбл с протоколом последовательности:
>>> class A:
...     def __getitem__(self, v):
...         return 'abc'[v]
... 
>>> a = A()
>>> it = iter(a)
>>> it
<iterator object at 0xb7381e4c>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB