Подробный пошаговый гайд по переходу с Python 2.7 на Python 3
Учитывая, что на дворе ноябрь 2026 года, переход с Python 2.7 на Python 3 — это не просто вопрос обновления синтаксиса, а критическая необходимость. Python 2.7 официально прекратил поддержку (EOL) 1 января 2020 года. Использование этой версии в продакшене сегодня означает отсутствие патчей безопасности и несовместимость с современным экосистемой.
Этап 1: Подготовка и Аудит
Прежде чем трогать код, необходимо оценить масштаб бедствия и подготовить инфраструктуру.
- Аудит зависимостей (Third-party libraries)
Убедитесь, что все используемые библиотеки поддерживают Python 3.
- Используйте утилиту
caniusepython3(если она еще доступна в вашем окружении) или просто проверьте PyPI. - Замените устаревшие библиотеки на их современные аналоги (например,
requestsвместоurllib2,psycopg2илиasyncpgдля баз данных).
- Используйте утилиту
- Покрытие тестами Никогда не начинайте миграцию без тестов. Python 3 ведет себя иначе (особенно в работе со строками и байтами), и без автоматических тестов вы рискуете получить скрытые баги.
- Создание ветки
Создайте отдельную ветку в Git (например,
feature/python3-migration), чтобы изолировать изменения.
Этап 2: Автоматическая конвертация
В 2026 году ручная правка синтаксиса — это прошлый век. Используйте инструменты автоматизации.
1. Встроенный инструмент 2to3
Он входит в стандартную поставку Python и переводит базовый синтаксис.
# Конвертация одного файла с записью изменений
2to3 -w my_script.py
# Конвертация целой директории
2to3 -w -n --no-backups /path/to/your/project
Минус:
2to3 делает код работающим на Python 3, но не заботится о том, чтобы он выглядел современно.
2. Современный подход: pyupgrade и ruff
После того как 2to3 сделал базовую работу, используйте современные линтеры и форматтеры, чтобы привести код к стандартам Python 3.10+.
pip install pyupgrade ruff
# pyupgrade удалит лишние префиксы u"", обновит форматирование строк (f-strings) и синтаксис type hints
pyupgrade --py310-plus $(find . -name "*.py")
Этап 3: Шпаргалка по ручным изменениям (Самые частые проблемы)
Автоматика не всегда справляется с семантическими изменениями.
Вот что вам придется править руками:
1. Строки и Байты (Самая частая причина багов)
В Python 2 str — это байты, а unicode — это текст. В Python 3 str — это Unicode (текст), а bytes — это байты.
- Python 2:
s = "текст"(байты),u = u"текст"(юникод). - Python 3:
s = "текст"(юникод),b = b"bytes"(байты). - Решение: Явно указывайте префикс
bдля байтовых строк. Добавьте# -*- coding: utf-8 -*-в начало файлов (в Py3 это по умолчанию, но помогает IDE).
2. Функция print
- Python 2:
print "Hello", name - Python 3:
print("Hello", name) - Совет: Если вы используете
from __future__ import print_function, код будет работать и там, и там.
3. Деление чисел
- Python 2:
5 / 2 = 2(целочисленное деление). - Python 3:
5 / 2 = 2.5(вещественное деление). - Решение: Используйте
//для целочисленного деления:5 // 2.
4. Исключения (Exceptions)
- Python 2:
except ValueError, e:илиraise ValueError, "message" - Python 3:
except ValueError as e:иraise ValueError("message")
5. Итераторы и Списки
Многие функции, возвращавшие списки в Py2, теперь возвращают итераторы (view objects) в Py3.
dict.keys(),dict.values(),dict.items()(вместоiterkeys,itervalues,iteritems).map(),filter(),zip().xrange()полностью удалена, используйтеrange().- Решение: Если вам нужен именно список, оборачивайте вызовы в
list():list(my_dict.items()).
6. Импорт модулей
В Python 3 по умолчанию используются абсолютные импорты.
- Python 2:
import utils(может найтиutils.pyв текущей папке). - Python 3:
import utils(ищет только вsys.path). - Решение: Используйте относительные импорты для внутренних модулей:
from . import utilsилиfrom .utils import func.
Этап 4: Изменения в Стандартной Библиотеке
Многие модули были переименованы или реорганизованы.
Вам придется заменить их в import:
| Python 2.7 | Python 3 |
|---|---|
__builtin__ |
builtins |
ConfigParser |
configparser |
copy_reg |
copyreg |
Queue |
queue |
SocketServer |
socketserver |
repr |
reprlib |
urllib2 |
urllib.request, urllib.error |
urlparse |
urllib.parse |
HTMLParser |
html.parser |
xmlrpclib |
xmlrpc.client |
Tkinter |
tkinter |
Лайфхак:
Для работы с сетью в Python 3 настоятельно рекомендую отказаться от urllib в пользу библиотеки requests или httpx (если нужна асинхронность).
Этап 5: Подводные камни и Отладка
1. Ошибка UnicodeDecodeError / UnicodeEncodeError
В Python 2 при склейке str и unicode происходило неявное декодирование (часто с ошибкой, если там были кириллические символы). Python 3 запрещает неявное смешивание байтов и строк.
Как лечить:
Найдите место, где читаются файлы или сетевые ответы, и явно указывайте кодировку: open('file.txt', 'r', encoding='utf-8').
2. Сравнение типов
В Python 2 можно было сравнить строку и число ("a" < 5), и это не вызывало ошибки. В Python 3 это выбросит TypeError. Проверьте код на наличие таких сравнений.
3. Методы словарей
Удалены dict.has_key(). Используйте оператор in: if key in my_dict:.
Этап 6: Пост-обработка (Современный Python 3)
После успешного запуска тестов на Python 3, прогоните код через следующие инструменты:
ruff— современный сверхбыстрый линтер и форматтер (заменяетflake8,isort,black).
pip install ruff
ruff check . --fix
ruff format .
- F-strings (появились в 3.6) — замените все
"Hello, %s" % nameи"Hello, {}".format(name)наf"Hello, {name}". - Type Hints (аннотации типов) — если проект большой, начните постепенно добавлять типы (PEP 484). В 2026 году это стандарт индустрии для поддержки легаси-кода.
pathlib— замените старыйos.pathна объектно-ориентированныйpathlib.
Чек-лист:
- [ ] Создана ветка в Git.
- [ ] Настроена CI/CD для запуска тестов на Python 3.12+ (или актуальной LTS версии).
- [ ] Запущен
2to3для базовой конвертации синтаксиса. - [ ] Вручную исправлены импорты (
urllib,Queueи т.д.). - [ ] Исправлены проблемы с кодировками (явное указание
encoding='utf-8'). - [ ] Запущены тесты, исправлены
TypeErrorиUnicodeError. - [ ] Прогнан
ruffиpyupgradeдля очистки кода от "шрамов" миграции. - [ ] Удален Python 2.7 из окружения и
Dockerfile/requirements.txt.
Мы делимся этой технической информацией, чтобы помочь вам в решении задач — используйте её с пониманием. Статья носит рекомендательный характер, поэтому, пожалуйста, применяйте описанные методы осмотрительно.