Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 12, 2015 15:57:26

taxik
Зарегистрирован: 2015-04-12
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Протоколы итерации

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

Отредактировано taxik (Апрель 12, 2015 16:03:33)

Офлайн

#2 Апрель 12, 2015 16:18:47

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Протоколы итерации

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



————————————————
-*- Simple is better than complex -*-

Офлайн

#3 Апрель 12, 2015 16:43:48

taxik
Зарегистрирован: 2015-04-12
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Протоколы итерации

terabayt
эмм.. что-то я не понял. list это список!
это я понимаю.)
terabayt
вот пример
Ваш класс C создает итератор для класса str, вы же в self.s передали строку. Получилась просто объертка.

Давайте попробуем так: в классе list нету метода __next__, но вызывая iter к его объекту, интерпритатор не ругается. Но когда мы делаем свой класс без __next__ и возвращаем в __iter__ self он ругается. Вопрос в том почему же он не ругается когда мы применяем iter к объекту list? Или еще можно так - что же такого делает __iter__ в классе list что __next__ вдруг появляется у итератора, вы же не думаете что там:
return iter([...])

Отредактировано taxik (Апрель 12, 2015 16:49:49)

Офлайн

#4 Апрель 12, 2015 16:50:47

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Протоколы итерации

taxik
вы же недумаете что там return iter()
а почему бы и нет?!
как сказал py.user.next
py.user.next
Он вызывает iter() для L и использует полученный объект для вызовов next().
iter, как я уже говорил, buil-in функция и я не вижу почему бы for или __iter__ не использовать его?
документация



————————————————
-*- Simple is better than complex -*-

Офлайн

#5 Апрель 12, 2015 16:58:03

taxik
Зарегистрирован: 2015-04-12
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Протоколы итерации

terabayt
а почему бы и нет?!
Такого не может быть, потому что получится бесконечная рекурсия. - чтобы получить итератор нужно получить итератор от самого себя…
iter() вызывает __iter__() объекта.

Офлайн

#6 Апрель 12, 2015 16:58:15

bismigalis
Зарегистрирован: 2010-10-02
Сообщения: 449
Репутация: +  47  -
Профиль   Отправить e-mail  

Протоколы итерации

может так будет понятней

>>> type([].__iter__())
<type 'listiterator'>

Офлайн

#7 Апрель 12, 2015 17:06:24

taxik
Зарегистрирован: 2015-04-12
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Протоколы итерации

bismigalis
может так будет понятней
Спасибо! я прозрел..))) Он просто возвращает объект другого класса который содержит __next__.

И terabayt спасибо за наводки.

Офлайн

#8 Апрель 12, 2015 23:43:14

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

Протоколы итерации

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
>>>



Отредактировано py.user.next (Апрель 13, 2015 00:06:01)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version