6 — Запись файлов | Питон и КИЛИ

Запись файлов

Содержание

  1. Запись файлов
  2. Чтение файлов построчно
  3. Домашнее задание

Запись файлов

Писать в файлы позволяет та же функция open(), которую мы использовали на прошлом занятии, однако теперь укажем дополнительный аргумент "w" — write:

>>> with open("referats.txt", "w", encoding="utf-8") as f:    # файл открыт
... 	# Записываем строку в файл, "\n" - символ переноса строки
... 	f.write("Используются тексты с Яндекс.Рефератов https://yandex.ru/referats/\n")
... 	# Запишем в файл еще одну строку
... 	f.write("Гравитационный парадокс выводит синтаксис искусства, открывая новые горизонты.\n")

Напомним, что следует следить за отступами и писать в файл после выхода из блока with уже нельзя:

>>> with open("function.txt", "w", encoding="utf-8") as f:
... 	f.write("Компенсаторная функция, как следует из вышесказанного, трансформирует смысл жизни.\n")
>>> if not f.writable:
... 	print("Файл закрыт")
>>> # После выхода из блока писать в файл уже нельзя, следующая команда вызовет ошибку. Как всегда следите за отступами!
>>> f.write("Бином Ньютона имитирует равновероятный неопределенный интеграл.\n")

Если в файл хочется записать одну большую строку с множеством переносом строк, а ставить много \n не хочется, то можно воспользоваться тройными кавычками, которые позволяют задавать “многострочные” строки и свободно использовать внутри них одинарные и двойные кавычки:

>>> text = """Альтиметр редуцирует лазерный ньютонометр. Как отмечает А.А.Потебня,
... "строфоид" начинает период. Необходимым и достаточным условием отрицательности
... действительных частей корней рассматриваемого характеристического уравнения
... является то, что гироскопический прибор преобразует цикл. Действительно,
... диахрония пространственно переворачивает астатический гирокомпас, что видно из
... уравнения кинетической энергии ротора. Погрешность изготовления неумеренно
... определяет резкий кинетический момент. Слово, несмотря на некоторую
... погрешность, поступательно диссонирует подвес. Апостроф' порождает неопределенность.
... """
>>> with open("multiline.txt", "w", encoding="utf-8") as f:
... 	f.write(text)

Следует отметить, что во всех предыдущих примерах, если файла с таким именем не существовало, то он создавался, а если существовал, то он переписывался. Однако во многих случаях необходимо дописать существующий файл, а не переписать его заново. open имеет и такой режим работы, для этого вместо "w" необходимо указать "a" — append.

>>> text = """Экситон не входит своими составляющими, что очевидно,
... в силы нормальных реакций связей, так же как и межатомный ПИГ,
... составляя уравнения Эйлера для этой системы координат.
... """
>>> # Создаем новый файл
>>> with open("physics.txt", "w", encoding="utf-8") as f:
...     f.write(text)
>>>
>>> # Теперь файл закрыт. Перепишем его
>>>
>>> # Стираем старый файл, создаем новый с тем же именем и открываем его для записи:
>>> with open("physics.txt", "w", encoding="utf-8") as f:
...     f.write("При погружении в жидкий кислород фотон искажает разрыв.\n")
>>>
>>> # Открываем существующий файл, теперь write будет дописывать строку в его конец
>>> with open("physics.txt", "a", encoding="utf-8") as f:
...     f.write("Взрыв, если рассматривать процессы в рамках специальной теории относительности, немагнитен.\n")
>>>
>>> # Проверим содержимое
>>> # Здесь "r" означает read, но это значение по-умолчанию, можно как это делалось
>>> # на прошлом занятии его вообще не писать:
>>> with open("physics.txt", "r", encoding="utf-8") as f:
...     first_line = f.readline()    # читаем первыую строку
...     # Проверяем, что строка начинается с данной подстроки:
...     if first_line.startswith("При погружении в жидкий"):
...         print("От экситона не осталось и следа")
...     second_line = f.readline().strip()    # читаем вторую строку и отрезаем ей \n
...     if second_line.endswith("теории относительности, немагнитен."):
...         print("Относительность относительна")

Чтение файлов построчно

Иногда бывает такое, что файлы очень большие и прочитать их целиком совсем никак не получается. Что, если вам нужно прочитать файл на 16 миллиардов строк, который весит десятки терабайт?

Да что там 16 миллиардов. Студенты порой жалуются, что на экзамене файл весит 50МБ и их программы долго его читают. Это не от того, что файл большой. Просто читают неправильно.

Какое здесь может быть решение? Очевидно, надо читать построчно. Но как?

У объекта, который возвращает функция open() есть много методов. В том числе метод .readlines(). По названию понятно, что делает этот метод - читает строки. Однако, в нашей задаче этот метод никак не поможет. Разберемся почему:

>>> file = open('borodino.txt')
>>> lines = file.readlines()
>>> print(type(lines))
>>> print(lines[:5])
>>> file.close()
<class 'list'>
['БОРОДИНО\n',
 '— Скажи-ка, дядя, ведь не даром\n',
 'Москва, спаленная пожаром,\n',
 'Французу отдана?\n',
 'Ведь были ж схватки боевые,\n']

Как мы видим, метод readlines() создает список строк всего файла. То есть тоже читает файл целиком.

Как же правильно прочитать построчно?

>>> with open('borodino.txt') as file:
...     i = 0
...     for line in file:
...         print(line, end='')
...         i += 1
...         if i >= 5:
...             break
БОРОДИНО
— Скажи-ка, дядя, ведь не даром
Москва, спаленная пожаром,
Французу отдана?
Ведь были ж схватки боевые,

При таком способе чтения python не будет считывать файл целиком, а будет считать построчно. То есть при чтении какого-угодно файла одновременно мы будем читать только одну строку. И 16 терабайт пройдут незаметно.

Домашнее задание

Для каждого варианта своё задание.

  1. Программа должна спрашивать у пользователя слова до тех пор, пока он не введёт пустое слово. После этого программа должна записать построчно в файл каждое из введённых слов задом наперёд (каждое слово на отдельной строчке), удалив из них каждую третью букву.

  2. Программа должна спрашивать у пользователя слова до тех пор, пока он не введёт пустое слово. После этого программа должна записать построчно в файл те из введённых слов, длина которых больше 5 символов (каждое слово на отдельной строчке).

  3. Программа должна спрашивать у пользователя слова до тех пор, пока он не введёт пустое слово. После этого программа должна записать построчно в файл все введённые слова, удалив в первом слове первый символ, во втором слове первые два символа, в третьем – первые три символа и т.д. (каждое слово на отдельной строчке).

  4. Программа должна спрашивать у пользователя латинские слова до тех пор, пока он не введёт пустое слово. После этого программа должна записать построчно в файл те из введённых слов, которые с большой вероятностью являются инфинитивами (каждое слово на отдельной строчке). [Словами типа esse можно не заморачиваться, но пассивный инфинитив надо учесть.]

  5. Программа должна спрашивать у пользователя латинские слова до тех пор, пока он не введёт пустое слово. После этого программа должна записать построчно в файл те из введённых слов, которые с большой вероятностью являются формой 3-го лица пассива настоящего времени (каждое слово на отдельной строчке). [Нерегулярными словами можно не заморачиваться.]

  6. Программа должна получить от пользователя подряд 7 чисел, а после этого записать в файл 7 строчек, состоящих из соответствующего числа букв X (на первой строчке количество иксов равно первому введённому числу, на второй – второму и т. д.; если введённое число отрицательно, иксов на этой строчке быть не должно). В задаче обязательно пользоваться списком, а не 7 переменными!

  7. Программа должна получить от пользователя подряд 8 слов, а после этого записать в файл 4 строчки с попарными склейками этих слов: на 1-й строчке – склеенные слова 1 и 2, на второй – 3 и 4 и т. д. В задаче обязательно пользоваться списком, а не 8 переменными!