Функции, строки и работа с файлами
Три навыка, без которых не написать ни одной серьёзной программы: разбивать код на функции, обрабатывать текст и работать с данными.
Функция — именованный блок кода, который принимает аргументы, выполняет действие и может вернуть результат; главный инструмент борьбы со сложностью.
Зачем это нужно
Когда программа вырастает, держать всё в голове невозможно. Функции позволяют разбить задачу на понятные кусочки, дать им имена и переиспользовать. Строки — это тексты, имена, ответы пользователя; их обработка встречается в каждой второй задаче. Файлы — способ сохранять данные между запусками. Эти три темы — рабочая повседневность программиста и основа заданий на обработку данных.
Главная идея, объединяющая весь урок, — борьба со сложностью через разбиение. Человеческий ум не способен одновременно удерживать сотню деталей, и единственный способ написать большую программу — резать её на части, каждая из которых умещается в голове целиком. Функция — основной инструмент такого разбиения: вы прячете кусок логики за понятным именем, и дальше думаете о нём как о «чёрном ящике» — что подаёшь, что получаешь, — не отвлекаясь на внутреннее устройство. Именно так строится любой серьёзный код: не одной простынёй, а как набор маленьких, проверяемых по отдельности функций. Строки и файлы добавляют к этому умение работать с реальными данными — ведь данные приходят к программе как текст (ввод пользователя, содержимое файла) и должны где-то сохраняться. Освоив эти три навыка, вы перестаёте писать «скрипты на один раз» и начинаете строить программы, которые можно развивать и поддерживать.
Функции: имя для куска логики
Функция получает данные через параметры и возвращает результат через return. Хорошая функция делает одно понятное дело. Напишем функцию, проверяющую, простое ли число — её можно вызывать сколько угодно раз:
def is_prime(n):
if n < 2:
return False
d = 2
while d * d <= n: # достаточно проверять до корня из n
if n % d == 0:
return False
d += 1
return True
for x in range(2, 20):
if is_prime(x):
print(x, end=" ")
print()
print("простых до 20 столько:", sum(1 for x in range(2, 20) if is_prime(x)))
Вывод:
2 3 5 7 11 13 17 19 простых до 20 столько: 8
Параметры по умолчанию и несколько возвращаемых значений
Параметрам можно задать значения по умолчанию, а вернуть можно сразу несколько величин (через кортеж). Это делает функции гибкими:
def stats(numbers, ndigits=2):
total = sum(numbers)
average = round(total / len(numbers), ndigits)
return total, average, max(numbers), min(numbers)
s, avg, hi, lo = stats([4, 8, 15, 16, 23, 42])
print("сумма:", s, " среднее:", avg, " макс:", hi, " мин:", lo)
# вызов с другим округлением
print(stats([1, 2, 2], ndigits=4))
Вывод:
сумма: 108 среднее: 18.0 макс: 42 мин: 4 (5, 1.6667, 2, 1)
Область видимости: локальное и глобальное
Переменная, созданная внутри функции, живёт только в ней — это локальная переменная. Снаружи её не видно. Это не ограничение, а защита: функции не мешают друг другу. Покажем разницу:
counter = 100 # глобальная
def demo():
counter = 5 # своя, локальная — не трогает глобальную
return counter
print("внутри функции:", demo())
print("снаружи:", counter) # глобальная не изменилась
Вывод:
внутри функции: 5 снаружи: 100
Строки: методы, которые решают половину задач
Строки неизменяемы, но богаты методами. split режет на части, join склеивает, strip убирает пробелы по краям, replace заменяет, upper/lower меняют регистр. Освойте их — и обработка текста станет лёгкой:
line = " Иванов; Петров; Сидоров "
names = line.strip().split(";") # убрали пробелы, разрезали
names = [n.strip() for n in names] # подчистили каждое
print("список:", names)
print("через запятую:", ", ".join(names))
print("заглавными:", names[0].upper())
print("начинается на 'Ив'?", names[0].startswith("Ив"))
Вывод:
список: ['Иванов', 'Петров', 'Сидоров'] через запятую: Иванов, Петров, Сидоров заглавными: ИВАНОВ начинается на 'Ив'? True
Форматирование строк (f-строки)
f-строки — самый удобный способ подставлять значения в текст. Внутри фигурных скобок можно писать выражения и указывать формат вывода:
name = "Аня"
score = 87.5
print(f"{name} набрала {score} баллов")
print(f"в процентах: {score/100:.1%}") # формат процента
print(f"число pi: {3.14159265:.3f}") # три знака после запятой
print(f"{42:>6}|{42:<6}|") # выравнивание по ширине 6
Вывод:
Аня набрала 87.5 баллов
в процентах: 87.5%
число pi: 3.142
42|42 |
Файлы: сохраняем и читаем данные
Файлы позволяют данным пережить завершение программы. Открывают файл конструкцией with open(...) as f — она гарантирует, что файл будет закрыт. Запишем числа в файл и прочитаем обратно. В песочнице файл создаётся во временной памяти браузера — код полностью рабочий:
# запись
with open("data.txt", "w", encoding="utf-8") as f:
for x in [10, 20, 30, 40]:
f.write(str(x) + "\n") # каждое число на своей строке
# чтение и обработка
total = 0
with open("data.txt", "r", encoding="utf-8") as f:
for line in f:
total += int(line.strip()) # strip убирает перевод строки
print("сумма чисел из файла:", total)
Вывод:
сумма чисел из файла: 100
Попробуй сам
Соберём всё в одну мини-программу: функция считает статистику по строке чисел, разделённых пробелами. Это типичный шаблон задач «на вход дана строка чисел».
def analyze(raw):
numbers = [int(x) for x in raw.split()]
return {
"count": len(numbers),
"sum": sum(numbers),
"max": max(numbers),
"even": [x for x in numbers if x % 2 == 0],
}
result = analyze("7 2 9 4 4 11 6")
for key, value in result.items():
print(f"{key}: {value}")
Вывод:
count: 7 sum: 43 max: 11 even: [2, 4, 4, 6]
Частые ошибки
- Забывают
return. Без него функция возвращаетNone, и результат «теряется». - Пытаются изменить строку по индексу. Строки неизменяемы; методы возвращают новую строку, а не меняют старую.
- Не убирают перевод строки при чтении файла. Каждая строка из файла оканчивается
\n; используйте.strip(). - Путают локальные и глобальные переменные. Присваивание внутри функции создаёт локальную переменную, не затрагивая глобальную.
Итоги
- Функция инкапсулирует логику: параметры на входе,
returnна выходе; можно возвращать несколько значений. - Локальные переменные живут только внутри функции — это защищает код от путаницы.
- Методы строк (
split,join,strip,replace) и f-строки покрывают большинство задач обработки текста. - Файлы открывают через
with open(...); при чтении не забывайтеstrip().