Перемещение кода Python 2 на Python 3
Python | Комментировать запись
Язык программирования Python был разработан в конце 1980-х, первый релиз вышел в 1991 году. Python назван в честь британской комедийной группы Monty Python и задуман как преемник императивного языка программирования ABC. Первая версия Python уже поддерживала обработку исключений, функции и классы с наследованием.
В этом руководстве вы узнаете, что нужно учитывать при переносе кода с Python 2 на Python 3 и как поддерживать код, совместимый с обеими версиями.
Кратко о версиях Python
Python 2 вышел в 2000 году. Новые функции этой версии позволили сделать процесс разработки более гибким и инклюзивным.
Версия Python 3 – будущее языка Python; в настоящее время эта версия находится в разработке. Выпущенная в конце 2008 года версия Python 3 учитывает и исправляет структурные недостатки предыдущих релизов. Тем не менее, внедрение Python 3 происходило довольно медленно, поскольку эта версия не совместима с Python 2.
Версия Python 2.7 вышла в 2010 году как последний релиз 2.x. Цель Python 2.7 – предоставить пользователям Python 2.x возможность переносить функции на Python 3, обеспечивая частичную совместимость между этими версиями.
Читайте также: Python 2 vs Python 3: краткий обзор и практические соображения
Начало работы с Python 2.7
Чтобы поддерживать Python 2 и Python 3 одновременно или полностью перейти на Python, необходимо убедиться, что код Python 2 полностью совместим с Python 2.7.
Сегодня многие разработчики пользуются исключительно кодом Python 2.7. Вы должны убедиться, что код, который поддерживается только более ранними версиями, корректно выполняется и совместим со стилем Python 2.7.
Обеспечить совместимость кода с Python 2.7 особенно важно, потому что это единственная версия Python 2, которая до сих пор поддерживается и исправляется. Если вы используете более раннюю версию Python 2, вам придется самостоятельно решать проблемы и искать способы исправления ошибок, поскольку версии 2.х больше не поддерживаются и не получают исправлений багов.
Кроме того, некоторые инструменты, которые облегчают перенос кода (например, пакет Pylint, который ищет ошибки в коде), не поддерживаются версиями Python до 2.7.
Важно иметь в виду следующее: хотя версия Python 2.7 поддерживается в настоящее время, её поддержка прекратится в 2020 году (согласно описанию релиза в PEP 373).
Пробный переход
Создание тестового кода является важной частью переноса кода Python 2 на Python 3. Если вы используете несколько версий Python, тестовый код должен покрывать все эти версии.
В рамках тестирования можно добавить интерактивные случаи Python в документацию всех функций, методов, классов и модулей, а затем использовать встроенный модуль doctest, чтобы проверить, как они работают.
Также можно использовать пакет coverage.py для отслеживания покрытий модуля. Этот инструмент следит, какие части кода были выполнены и какие части могли быть выполнены (но этого не произошло). Coverage.py может выводить результат в командной строке или выдавать HTML-вывод. Обычно этот пакет используется для измерения эффективности тестов; он сообщает, какие части кода выполняются при тестировании, а какие нет.
Имейте в виду: стремиться к 100% -му покрытию не нужно. На данном этапе нужно достаточно просто убедиться в покрытии запутанного и сложного кода. Результата в 80% будет вполне достаточно.
Различия между Python 2 и Python 3
Зная разницу между Python 2 и Python 3, вы сможете использовать новые функции и обеспечить правильный перенос кода.
Основные отличия описаны в статье Python 2 vs Python 3: краткий обзор и практические соображения. Более подробную информацию можно найти в официальной документации Python.
При переносе кода следует учитывать несколько изменений в синтаксисе.
В Python 2 print является оператором, а в Python 3 – функцией (print()).
Python 2 | Python 3 |
print “Hello, World!” | print(“Hello, World!”) |
exec
Оператор exec в Python 3 становится функцией с поддержкой локальных и глобальных переменных.
Python 2 | Python 3 |
exec code | exec(code) |
exec code in globals | exec(code, globals) |
exec code in (globals, locals) | exec(code, globals, locals) |
/ и //
Python 2 выполняет целочисленное деление с помощью оператора /, а Python 3 – с помощью //.
Python 2 | Python 3 |
5 / 2 = 2 | 5 / 2 = 2.5 |
5 // 2 = 2 |
Чтобы использовать эти операторы, импортируйте division модуля __future__:
from __future__ import division
raise
В Python 3 для добавления исключений с аргументами требуются круглые скобки; строки не могут использоваться в качестве исключений.
Python 2 | Python 3 |
raise Exception, args | raise Exception |
raise Exception(args) | |
raise Exception, args, traceback | raise Exception(args).with_traceback(traceback) |
raise “Error” | raise Exception(“Error”) |
except
В Python 2 было сложно перечислить несколько исключений, но Python 3 это уже не так. Обратите внимание: в Python 3 as явно используется вместе с except.
Python 2 | Python 3 |
except Exception, variable: | except AnException as variable: |
except (OneException, TwoException) as variable: |
def
В Python 2 функции могут принимать последовательные типы данных (например, кортежи или списки). В Python 3 эта функция отсутствует.
Python 2 | Python 3 |
def function(arg1, (x, y)): | def function(arg1, x_y): x, y = x_y |
expr
Синтаксис backtick Python 2 не поддерживается в Python 3. Вместо этого используются repr() или str.format().
Python 2 | Python 3 |
x = `355/113` | x = repr(355/113): |
Форматирование строк
В Python 3 меняется синтаксис форматирования строк.
Python 2 | Python 3 |
“%d %s” % (i, s) | “{} {}”.format(i, s) |
“%d/%d=%f” % (355, 113, 355/113) | “{:d}/[:d}={:f}”.format(355, 113, 355/113) |
Читайте также: Форматирование строк в Python 3
Классы и объекты
В Python не нужно указывать объект.
Python 2
class MyClass(object):
pass
Python 3
class MyClass:
pass
Метаклассы указываются с помощью ключевого слова metaclass.
Python 2
class MyClass:
__metaclass__ = MyMeta
class MyClass(MyBase):
__metaclass__ = MyMeta
Python 3
class MyClass(metaclass=type):
pass
class MyClass(MyBase, metaclass=MyMeta):
pass
Обновление кода
Существует два инструмента для автоматического обновления кода до Python 3. При этом код остаётся совместимым с Python 2. Эти инструменты – future и modernize. Каждый из этих инструментов ведет себя по-разному: future включает поддержку лучших функций Python 3 в Python 2, а modernize работает с подмножествами Python, которые используют модуль six.
Эти инструменты для обработки переноса кода могут выявить и исправить возможные проблемы и неясности.
Вы можете запустить инструмент во время тестирования, чтобы проверить код и убедиться, что автоматические изменения сделаны правильно. После прохождения тестов вы можете преобразовать свой код.
После этого следует просмотреть код и убедиться, что он учитывает все изменения синтаксиса, описанные в предыдущем разделе.
При использовании модуля future добавьте оператор import во все модули Python 2.7.
from __future__ import print_function, division, absolute_imports, unicode_literals
Это обеспечит соответствие кода Python 2 синтаксису Python 3.
Также можно использовать пакет pylint для выявления потенциальных проблем в коде. Этот пакет содержит сотни индивидуальных правил, которые охватывают широкий спектр потенциальных ошибок (включая правила PEP 8).
Код может содержать некоторые конструкции, которые могут запутать pylint и инструменты, используемые для автоматической миграции.
Непрерывная интеграция
Если вы собираетесь поддерживать свой код для нескольких версий Python, будьте очень внимательны, как можно чаще запускайте unittest путем непрерывной интеграции (а не вручную).
Если вы используете пакет six для поддержки совместимости с Python 2 и 3, создайте несколько сред для тестирования.
Одним из популярных средств управления средой является пакет tox. Он проверит установку пакета в различных версиях Python, проведет тесты в каждой среде и предоставит интерфейс для серверов непрерывной интеграции.
Заключение
Важно помнить, что чем больше внимания разработчиков и сообщества будет уделено версии Python 3, тем больше она будет соответствовать потребностям программистов. При поддержке кода версиями Python 2 и Python 3 возникают различные ошибки, которые со временем станет труднее исправлять.
Tags: Python 2, Python 2.7, Python 3