Что вы узнаете?

  • Открытие файлов
  • Чтение файлов
  • Итерация
  • Итераторы
  • Итерации
  • Генераторы
  • Урожай

Как открыть файл в python?

Открытие файла в python осуществляется с помощью встроенной функции: open

open(file, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

Допустим, у вас есть текстовый файл с именем words, вы можете открыть его следующим образом:

words = open("words.txt", "r")

где words — объект файлового потока, а r — режим чтения.

Как прочитать файл в python?

При открытии файла функция открытиявозвращает объект файлового потока,

Указанный объект файлового потока имеет методы, которые позволяют нам читать содержимое файла,

Один из способов открыть, прочитать и закрыть файл выглядит следующим образом:

fstream = open("words.txt", "r")
content = fstream.read()
# do something with the content
print(content)
# close file
fstream.close()

где content — это строковая переменная, содержащая содержимое файла в памяти.

Если мы хотим неявно закрыть файл, мы можем сделать это следующим образом:

with open("words") as fstream:
    content = fstream.read()

Оператор Where with заботится о закрытии файла, поскольку он знает, как обращаться с файловыми потоками.

Что не так с описанным выше подходом?

чтение большого файла с использованием вышеуказанного метода проблематично и приведет к ненужному переполнению памяти, поскольку он пытается загрузить ВЕСЬ контент сразу в память, где никогда не будет достаточно места для этого огромного объема данных.

Итак, как это обойти?

Представляем итерацию, итераторы, итерации, генераторы и ключевое слово yield…

Что такое итерация?

Это процесс итерации/перебора элементов в коллекции (List, Dictionary, Tuple являются примерами коллекции).

Что такое итератор?

Объект, представляющий последовательность данных, к которым можно обращаться по одному за раз,

Итератор Python следует протоколу итератора, поэтому он реализует и предоставляет метод next(), который возвращает следующий элемент в итерируемом объекте.

Кроме того, важно отметить, что с помощью итераторов python (PVM) может выполнять итерацию по коллекции, такой как списки (например: in for … in statement), другими словами, под капотом, for … в цикле делает использование указанного итератора коллекции для перебора элементов коллекции.

Что такое итерируемый объект?

Любой объект, реализующий функцию __iter__, называется итерируемым.

указанная функция возвращает итератор

Списки, словари, кортежи в python являются примером итерируемых объектов, поскольку они реализуют указанную функцию, например:

>>> numbers = [1,2,3]
>>> numbers_iter = numbers.__iter__()
>>> numbers_iter.__next__()
1
>>> numbers_iter.__next__()
2
>>> numbers_iter.__next__()
3
>>> numbers_iter.__next__()
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    numbers_iter.__next__()
StopIteration

Обратите внимание, что итератор вызывает исключение StopIteration, когда не осталось оставшихся значений.

Что такое генератор?

Специальный тип итератора, в котором последовательность данных лениво загружается в память, по одному за раз, что делает его идеальным для чтения большого объема данных.

Глядя на определение генератора:

Из вышеприведенного определения можно понять, что генератор является итератором, а также итерируемым объектом.

Что такое ключевое слово доходность?

Это ключевое слово используется для возврата генератора в функциях генератора,

другими словами, то, что делает функцию функцией-генератором, — это наличие yield в теле функции.

Что особенного в yield, так это его способность приостанавливать выполнение функции генератора и возвращатьвыданное значение вызывающей стороне, при этом функция состояние, а также другие сведения сохраняются для следующего обращения.

Соединяем кусочки

Предположим, у нас есть текстовый файл с именем words, этот файл содержит несколько случайных слов, разделенных новой строкой, и мы хотим найти самое длинноеслово и распечатать его, давайте также предположим, что размер файла составляет 100 МБ.

Вот как это можно сделать:

# this generator function returns a generator in each yield hit
def read_words(filename):
    file = open(filename, "r")
    for line in file:
        yield line
    # the file won't close automatically since 
    # we don't use with statement thus we need to explicitly close it
    file.close()

def find_max_word() -> str:
    max_word_len = 0
    max_word = None
    # since the generator function returns a generator
    # and the generator is a special type of iterator
    # we can simply iterate over it using for .. in
    for yielded_word in read_words("test.txt"):
        # remove newline and line break characters
        word = yielded_word.strip()
        len_of_word = len(word)
        if len_of_word > max_word_len:
            max_word = word
            max_word_len = len_of_word
    return max_word

max_word = find_max_word()
print(max_word)

где read_words — функция генератора.