#python #python_3x #генераторы #динамическая_типизация
У меня есть класс в котором я переопределяю метод __next __ после его первого вызова,
но проблема в том что работать продолжает старый __next __.
class I:
def __init__(self, head):
self.head = iter(head)
def __iter__(self):
return self
def __next__(self):
self.__next__ = self.head.__next__
return 'a'
i = I((1, 2, 3))
i_it = iter(i)
print(next(i_it)) #выводит 'a'. Все ок
print(next(i_it)) #снова 'a'. Почему не 1?
print(i_it.__next__) #
вроде __next__ переопределен
P.S Если переопределять что-то другое то все работает:
def __next__(self):
self.__next__ = self.head.__next__
self.x = 1
return 'a'
После вызова next(self) x будет 1.
Ссылка на онлайн компилятор: https://repl.it/HVOC/17
P.P.S: В коментариях говорят что если вызывать i_it.__next __() то все будет работать
так как надо, я это знаю, но штука в том что в любом итераторе(цикл for например) работает
next(self), а не self.__next __().
Ответы
Ответ 1
На сколько я понимаю, в cpython встроенная функция next() определяется тут: builtin_next(). Можно увидеть, что при вызове имеется следующая конструкция: res = (*it->ob_type->tp_iternext)(it); Полагаю, что она равносильна примерно такой конструкции на Python: next(i) --> i.__class__.__next__(i) что сходится с тем, что видно на практике. Как дела происходят в других интерпретаторах мне не известно.Ответ 2
Сначала i_it.__next__ = i.__next__. Затем i.__next__ = self.head.__next__ Но i_it.__next__ остался прежним, тк его не меняли. Те __next__ был изменен только для объекта класса i, но не для итератора i_it
Комментариев нет:
Отправить комментарий