#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
Комментариев нет:
Отправить комментарий