Python: функции, файлы, обработка ошибок¶
Справочник вопросов для самопроверки: циклы, функции, файлы и исключения в Python с параллелями в Go.
1. Операторы цикла: while, for, range, continue, break, else¶
В Python while повторяет тело, пока условие истинно, а for итерируется по любому итерируемому объекту (список, строка, range, генератор). range(start, stop, step) задаёт ленивую последовательность чисел, не строя список целиком. break досрочно выходит из цикла, continue пропускает остаток текущей итерации. Особенность Python — else у цикла: его блок выполняется, только если цикл завершился штатно (не через break), что удобно для поиска без флага-«нашли».
for x in range(10):
if x == target:
break
else:
print("не найдено") # сработает, только если break не случился
В Go только один универсальный for (он же while и бесконечный цикл), есть range для слайсов/мап/каналов, но конструкции for...else нет.
2. Ввод и вывод данных¶
print(*objects, sep=' ', end='\n', file=sys.stdout) выводит значения в поток, по умолчанию в stdout, разделяя пробелом и добавляя перевод строки. input(prompt) читает одну строку из stdin и всегда возвращает строку — число нужно приводить явно (int(input())). Для вывода в stderr указывают print(..., file=sys.stderr).
В Go вывод — fmt.Println/fmt.Printf (с форматными глаголами вроде %d, %s), а ввод — fmt.Scan/fmt.Scanln или bufio.Scanner для построчного чтения; типы там определяются сразу, без ручного приведения строки.
3. Встроенные функции Python¶
Python даёт богатый набор встроенных функций без импорта: len() — длина, range() — последовательность чисел, enumerate() — пары (индекс, элемент), zip() — поэлементное объединение нескольких последовательностей. Функциональные map(func, it) и filter(pred, it) возвращают ленивые итераторы, sorted() отдаёт новый отсортированный список (с key= и reverse=), а sum(), min(), max() агрегируют. Для интроспекции типов служат type(x) (точный тип) и isinstance(x, T) (проверка с учётом наследования).
В Go аналогов в виде встроенных функций мало (len, cap, append); сортировка и map/filter делаются явными циклами или пакетами sort/slices.
4. Понятие подпрограммы. Область видимости¶
Подпрограмма (функция) — именованный блок кода, который вызывается по имени, принимает аргументы и возвращает результат, что устраняет дублирование. Видимость имён в Python подчиняется правилу LEGB: интерпретатор ищет имя в порядке Local → Enclosing (объемлющая функция) → Global → Built-in. Чтобы изменить внешнее имя изнутри функции, нужны global или nonlocal, иначе присваивание создаёт новую локальную переменную.
В Go область видимости блочная и лексическая: переменная видна в своём блоке {} и вложенных; вложенных функций-замыканий тоже хватает, но явных ключевых слов вроде global нет — управление идёт через пакетные переменные и передачу по ссылке.
5. Аргументы функции¶
Python поддерживает несколько видов аргументов: обязательные позиционные, ключевые (передаются по имени), со значением по умолчанию (def f(x, n=1)). Звёздочные формы собирают переменное число: *args — кортеж лишних позиционных, **kwargs — словарь лишних ключевых. Важная ловушка: изменяемое значение по умолчанию (список, словарь) создаётся один раз и переживает между вызовами — используйте None как маркер.
В Go нет аргументов по умолчанию и ключевых аргументов; переменное число даёт ...T (variadic), а «опции» обычно эмулируют структурой настроек или паттерном functional options.
6. Анонимные функции lambda¶
lambda — анонимная функция из одного выражения: lambda x: x * 2. Уместна как короткий callback там, где определять def избыточно — например, в key= для sorted() или в map/filter. Ограничения существенны: тело — только одно выражение (никаких операторов, циклов, присваиваний), нет имени для трассировки, поэтому для нетривиальной логики предпочитают обычную функцию.
В Go все функции по сути могут быть анонимными литералами (func(x int) int { return x*2 }), и они полноценны — никакого ограничения «одно выражение» нет.
7. Секреты хорошей функции¶
Хорошая функция следует принципу единственной ответственности (SRP): делает одну вещь и делает её хорошо. Желательны чистота (результат зависит только от аргументов, без скрытых побочных эффектов) и по возможности идемпотентность (повторный вызов с теми же данными не ломает состояние) — это критично для SRE-скриптов, которые могут перезапускаться. Дополнительно: говорящее имя (глагол + объект), малое число аргументов (много параметров — сигнал, что стоит сгруппировать их в структуру/класс).
8. Декораторы (Python) и middleware (Go)¶
Декоратор — функция, которая принимает другую функцию и возвращает новую, обёртывающую её поведение (логирование, замер времени, кэш, ретраи) без изменения исходного кода. Синтаксис @decorator над def — это сахар для f = decorator(f); обычно внутри используют functools.wraps, чтобы сохранить имя и docstring обёрнутой функции.
В Go прямого аналога-синтаксиса нет, но идею даёт middleware: функция вида func(next http.Handler) http.Handler, оборачивающая обработчик, — те же сквозные задачи (аутентификация, логи) навешиваются цепочкой вокруг основного хендлера.
9. Рекурсия¶
Рекурсия — приём, когда функция вызывает саму себя для решения подзадачи. Корректная рекурсия обязана иметь базовый случай (условие остановки) и рекурсивный шаг, приближающий к базовому; иначе вызовы не завершатся. В Python есть предел глубины (по умолчанию ~1000), и при его превышении возникает RecursionError — риск переполнения стека, поэтому глубокую рекурсию часто переписывают в цикл.
В Go тоже нет автоматической оптимизации хвостовой рекурсии, поэтому для больших глубин предпочитают итерацию.
10. Регулярные выражения¶
Регулярные выражения — язык шаблонов для поиска и разбора строк: извлечь IP из лога, проверить формат, заменить подстроки. В Python работают через модуль re (re.search, re.findall, re.sub); тяжёлые шаблоны полезно заранее компилировать через re.compile.
В Go это пакет regexp (regexp.MustCompile(...).FindString(...)), использующий безопасный по времени движок RE2 без катастрофического бэктрекинга.
11. Организация доступа к файлам. Файловый объект¶
Доступ к файлу начинается с open(path, mode), который возвращает файловый объект с методами read, readline, write, close. Правильный способ — менеджер контекста with, гарантирующий закрытие файла даже при исключении. Режимы: 'r' (чтение), 'w' (перезапись), 'a' (дозапись), 'x' (создать новый), '+' (чтение+запись). Запись по умолчанию буферизуется — данные могут попасть на диск не сразу, для принудительного сброса есть flush().
В Go это os.Open/os.Create, отложенное закрытие через defer f.Close(), а буферизацию даёт bufio.
12. Типы файлов¶
Файлы делятся на текстовые и бинарные. В текстовом режиме ('t', по умолчанию) Python декодирует байты в строки str по кодировке (encoding='utf-8') и нормализует переводы строк. В бинарном режиме ('b', например 'rb'/'wb') данные читаются и пишутся как bytes без всякого декодирования — это нужно для изображений, архивов, сетевых форматов.
В Go такого разделения на уровне открытия нет: файл всегда поток байт, а «текстовость» — это уже интерпретация при чтении (например, через bufio.Scanner).
13. Файлы произвольного доступа¶
Кроме последовательного чтения, в файле можно перемещать позицию (курсор): f.seek(offset, whence) устанавливает позицию, f.tell() сообщает текущую — это и есть произвольный доступ. Для записи структурированных бинарных данных по фиксированному формату в Python служит модуль struct (struct.pack/struct.unpack с форматной строкой вроде ">I4s").
В Go аналогичную сериализацию бинарных полей с указанием порядка байт даёт пакет encoding/binary (binary.Read/binary.Write, binary.BigEndian).
14. Ошибки и исключения¶
Python использует механизм исключений: рискованный код кладут в try, обработку — в except (можно по типу: except ValueError), блок else выполняется при отсутствии ошибки, а finally — всегда (очистка ресурсов). Своё исключение возбуждают через raise. Это модель «проще просить прощения, чем разрешения» (EAFP).
В Go подход иной: ошибка — это обычное возвращаемое значение типа error, проверяемое идиомой if err != nil; panic/recover оставляют лишь для действительно неустранимых сбоев, а не для штатной обработки.