Форум сайта python.su
Здравствуйте, подскажите пожалуйста в книге Dive into python есть пример создания итератора в файле plural6.py , код там такой
def __init__(self): self.pattern_file = open(self.rules_filename, encoding='utf-8') self.cache = [] def __iter__(self): self.cache_index = 0 return self def __next__(self): self.cache_index += 1 if len(self.cache) >= self.cache_index: return self.cache[self.cache_index - 1] if self.pattern_file.closed: raise StopIteration line = self.pattern_file.readline() if not line: self.pattern_file.close() raise StopIteration pattern, search, replace = line.split(None, 3) funcs = build_match_and_apply_functions( pattern, search, replace) self.cache.append(funcs) return funcs
if len(self.cache) >= self.cache_index: return self.cache[self.cache_index - 1]
Офлайн
dobriy_dadaОн для второго прохода так сделан. При первом проходе правила кешируются и остаются для последующих проходов. При следующем проходе сначала просматривается кеш, пока в нём не закончатся правила, а потом продолжается чтение правил из файла (с добавлением их в кеш).
как может индекс быть меньше, если он увеличивается перед добавлением в список self.cache ?
Отредактировано py.user.next (Янв. 6, 2016 00:53:14)
Офлайн
Спасибо, теперь начинает доходить :-)
То есть допустим мы определили множественное число для первого слова, а для второго слова кэш с функциями (self.cache) уже заполнен, и строка
if len(self.cache) >= self.cache_index:
Отредактировано dobriy_dada (Янв. 6, 2016 09:53:18)
Офлайн
dobriy_dadaЭто не проход, проход - это когда ты весь итератор исчерпал, взяв все его элементы.
Допустим, что при первом проходе будет следующее:
>>> class A: ... def __iter__(self): ... self.it = iter('abc') ... return self ... def __next__(self): ... return next(self.it) ... >>> a = A() >>> >>> it = iter(a) >>> next(it) 'a' >>> next(it) 'b' >>> next(it) 'c' >>> next(it) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in __next__ StopIteration >>> >>> it = iter(a) >>> next(it) 'a' >>> next(it) 'b' >>> next(it) 'c' >>> next(it) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in __next__ StopIteration >>>
>>> class A: ... def __iter__(self): ... self.it = iter('abc') ... return self ... def __next__(self): ... return next(self.it) ... >>> a = A() >>> >>> for i in a: ... i ... 'a' 'b' 'c' >>> for i in a: ... i ... 'a' 'b' 'c' >>>
Отредактировано py.user.next (Янв. 6, 2016 10:07:38)
Офлайн
dobriy_dadaНе меняй сообщения, которые написал, иначе теряется линия беседы.
Спасибо, теперь начинает доходить :-)
Офлайн
спасибо :-)
Офлайн
Вопрос по тому же коду, а именно к вот этой части:
def __iter__(self): self.cache_index = 0 return self
Отредактировано endless_lama (Ноя. 24, 2017 10:05:49)
Офлайн
endless_lamaЭтот итератор достаёт правила из файла. Когда он достаёт правило, он его записывает в кеш. А тому, кто использует этот итератор, нужно получить первое подходящее правило. То есть может получиться ситуация, где нужное правило находится в середине файла. После того как правило найдено, итератор отбрасывается и больше не используется.
Но я не очень понимаю, зачем нужно, чтобы self.cache_index = 0? Зачем нужно его каждый раз ресетить?
Отредактировано py.user.next (Ноя. 24, 2017 11:57:48)
Офлайн
Большое спасибо за подробное объяснение! То есть self.cache_index = 0 значит, что “указатель” кеша сбрасывается на начало кеша? Или значит, что кеш пустой? Я вот это не очень понимаю..
Отредактировано endless_lama (Ноя. 24, 2017 16:02:59)
Офлайн
endless_lamaЛюбой итератор работает так: сначала его надо построить, потом можно получать из него элементы.
То есть self.cache_index = 0 значит, что “указатель” кеша сбрасывается на начало кеша?
endless_lamaКеш никогда не опустошается, только растёт. Но чтобы читать из него правила для каждого нового слова (а это нужно делать каждый раз с самого начала), индекс кеша ставится на начало кеша.
Или значит, что кеш пустой?
Офлайн