Страницы

Поиск по вопросам

среда, 22 мая 2019 г.

Атрибут __next__ не переопределяется

У меня есть класс в котором я переопределяю метод __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 __().


Ответ

На сколько я понимаю, в cpython встроенная функция next() определяется тут: builtin_next(). Можно увидеть, что при вызове имеется следующая конструкция:
res = (*it->ob_type->tp_iternext)(it);
Полагаю, что она равносильна примерно такой конструкции на Python:
next(i) --> i.__class__.__next__(i)
что сходится с тем, что видно на практике.
Как дела происходят в других интерпретаторах мне не известно.

Комментариев нет:

Отправить комментарий