- Записывать в файл и читать из него через
with open(...) - Различать режимы
'r','w'и'a' - Объединять переменные, циклы, функции, словари и обработку ошибок в одной программе
Как только программа завершается, все переменные стираются из памяти: рекорд в игре, оценки в журнале, список покупок — всё исчезает. Чтобы сохранить данные, их нужно записать в файл. В этом уроке ты научишься работать с файлами, а затем объединишь всё, что узнал за курс, в одном настоящем проекте — калькуляторе оценок.
Запись и чтение файлов
Функция open() открывает файл: первый аргумент — имя файла, второй — режим. Оператор with автоматически закрывает файл, когда блок заканчивается, — даже если произошла ошибка. А encoding='utf-8' гарантирует, что буквы вроде ё, щ или ş сохранятся правильно.
| Режим | Значение | Если файл уже есть |
|---|---|---|
'r' | чтение (по умолчанию) | содержимое читается; если файла нет — FileNotFoundError |
'w' | запись | старое содержимое стирается |
'a' | дозапись в конец | новый текст добавляется в конец |
with open('notes.txt', 'w', encoding='utf-8') as f:
f.write('Python is fun\n')
f.write('Files keep data\n')
with open('notes.txt', encoding='utf-8') as f:
for line in f:
print(line.strip())▸ Ожидаемый результат
Python is fun Files keep data
write() не добавляет перевод строки, поэтому \n мы пишем сами. При чтении файла по строкам в цикле for этот \n остаётся в конце каждой строки — strip() его убирает. Чтобы сразу получить все строки списком, используют readlines():
with open('log.txt', 'w', encoding='utf-8') as f:
f.write('Day 1: started Python\n')
with open('log.txt', 'a', encoding='utf-8') as f:
f.write('Day 2: learned loops\n')
with open('log.txt', encoding='utf-8') as f:
lines = f.readlines()
print(len(lines), 'lines')
print(lines[-1].strip())▸ Ожидаемый результат
2 lines Day 2: learned loops
Если попытаться прочитать несуществующий файл, возникнет FileNotFoundError. Как в уроке об обработке ошибок, его можно перехватить через try / except:
try:
with open('missing.txt', encoding='utf-8') as f:
print(f.read())
except FileNotFoundError:
print('File not found, starting with an empty list.')▸ Ожидаемый результат
File not found, starting with an empty list.
Мини-проект: калькулятор оценок
Учитель хранит оценки учеников в простом текстовом файле: в каждой строке имя и оценки через запятую. Такой формат называется CSV (comma-separated values — значения, разделённые запятыми). Наша программа прочитает файл, пропустит ошибочные строки, посчитает средний балл каждого ученика и запишет отчёт в новый файл.
- 1Подготовь данные
Запиши оценки в файл
grades.csv. В одну строку специально добавим ошибку (x), чтобы посмотреть, как программа на неё отреагирует. - 2Прочитай и разбери файл
Раздели каждую строку через
split(','): первая часть — имя, остальные — оценки. Преобразуй их черезint()и сохрани в словарь. - 3Перехвати ошибки
int('x')вызоветValueError— перехвати его черезtry/except, выведи предупреждение и пропусти эту строку. - 4Посчитай и запиши отчёт
С помощью функций найди средний балл и уровень, запиши результаты в
report.txtи прочитай файл, чтобы проверить.
lines = ['Aysel,5,4,5,5', 'Murad,4,3,4', 'Leyla,5,5,4,5', 'Elvin,3,x,4', 'Nigar,2,3,3']
with open('grades.csv', 'w', encoding='utf-8') as f:
f.write('\n'.join(lines))
journal = {}
with open('grades.csv', encoding='utf-8') as f:
for line in f:
parts = line.strip().split(',')
name = parts[0]
try:
journal[name] = [int(m) for m in parts[1:]]
except ValueError:
print(f'Skipped {name}: bad data')
print(journal)▸ Ожидаемый результат
Skipped Elvin: bad data
{'Aysel': [5, 4, 5, 5], 'Murad': [4, 3, 4], 'Leyla': [5, 5, 4, 5], 'Nigar': [2, 3, 3]}parts[1:] берёт все части после имени.Теперь разделим расчёт на две функции: average возвращает средний балл, а level — уровень словом (пороги мы выбрали сами). Генератор словаря считает все средние одной строкой, а результат записывается в файл report.txt:
journal = {'Aysel': [5, 4, 5, 5], 'Murad': [4, 3, 4], 'Leyla': [5, 5, 4, 5], 'Nigar': [2, 3, 3]}
def average(scores):
return sum(scores) / len(scores)
def level(avg):
if avg >= 4.5:
return 'excellent'
elif avg >= 3.5:
return 'good'
elif avg >= 2.5:
return 'satisfactory'
return 'needs help'
averages = {name: average(s) for name, s in journal.items()}
with open('report.txt', 'w', encoding='utf-8') as f:
for name, avg in averages.items():
f.write(f'{name}: {avg:.2f} ({level(avg)})\n')
with open('report.txt', encoding='utf-8') as f:
print(f.read().strip())
print(f'Best average: {max(averages.values()):.2f}')▸ Ожидаемый результат
Aysel: 4.75 (excellent) Murad: 3.67 (good) Leyla: 4.75 (excellent) Nigar: 2.67 (satisfactory) Best average: 4.75
Запиши каждый фрукт из списка fruits в файл fruits.txt на отдельной строке (режим 'w'). Затем прочитай файл и выведи его строки с номерами от 1, в виде 1. apple.
fruits = ['apple', 'pomegranate', 'fig']
# 1) write each fruit on its own line to fruits.txt
# 2) read fruits.txt and print: 1. apple, 2. pomegranate, ...▸ Ожидаемый результат
1. apple 2. pomegranate 3. fig
Мини-проект: каждая строка файла sales.csv имеет вид товар,количество,цена. Прочитай файл и сложи в словаре выручку по каждому товару (количество × цена). Строку с ошибочными данными пропусти с помощью try/except и выведи Skipped: и эту строку. В конце выведи товары в алфавитном порядке в виде cup: 2.00 AZN, а последней — строку Total: в том же формате.
lines = ['pen,3,0.5', 'notebook,2,1.25', 'bag,1,x', 'pen,4,0.5']
with open('sales.csv', 'w', encoding='utf-8') as f:
f.write('\n'.join(lines))
totals = {}
# 1) read sales.csv line by line: product,quantity,price
# 2) skip bad lines (print Skipped: and the line)
# 3) add quantity * price to totals[product]
# 4) print the products in alphabetical order, then the Total▸ Ожидаемый результат
Skipped: bag,1,x notebook: 2.50 AZN pen: 3.50 AZN Total: 6.00 AZN
Главное
with open(имя, режим, encoding='utf-8') as f:открывает файл и автоматически закрывает его в конце блока.'r'— чтение,'w'— запись со стиранием,'a'— дозапись в конец.write()не добавляет\n; из прочитанных строк\nубираетstrip().- Чтение несуществующего файла вызывает
FileNotFoundError— перехватывай его черезtry/except. - Строки CSV можно разбить на части с помощью
split(',').
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.