Разница между Python 2 и Python 3 на примерах — Какую версию выбрать?

Разница между Python 2 и 3

Многие пользователи задаются вопросом, с какой версии Python следует начинать изучение данного языка. Зачастую новички останавливаются на версии, которая фигурирует в рассматриваемом ими учебном пособии.

Содержание статьи

Однако, как быть, если при создании нового проекта у вас есть выбор? Можно сказать, что если обе версии поддерживают библиотеки, которые вы планируете использовать, нет нужды особо волноваться. Тем не менее, будет не лишним взглянуть на основные различия между Python 2 и 3. Это поможет избежать распространенных ошибок при написании кода или определиться с выбором для будущего проекта.

Что такое Python 2?

В свое время появление Python 2 значительно упростило процесс разработки кода в сравнении с предыдущими версиями. Теперь были реализованы технические детали Python Enhancement Proposal (PEP).

Python 2.7 (последняя версия в 2.x) больше не разрабатывается. После 2020 года поддержка также прекратится окончательно.

Что такое Python 3?

В декабре 2008 года вышла новая версия Python — 3.0. Версия была выпущена для исправления проблем, присущих Python 2. Важно понимать, что Python 3 несовместим с Python 2. Это обратная несовместимость. Некоторые аспекты Python 3 были перенесены обратно в Python 2.x, чтобы сделать процесс миграции легче в Python 3.

В результате для любой организации, которая использовала версию Python 2.x, миграция проекта на 3.x требовала большого количества изменений. Эти изменения касаются не только проектов и приложений, но и всех библиотек, которые являются частью экосистемы Python.

Что нужно знать о Python 2?

python2 vs python3

Тренды Google в отношении Python 2 vs. Python 3

Хотя на сегодняшний день Python 2 является уже устаревшей версией с открытым кодом, на определенные моменты стоит обратить особое внимание:

  • Для того чтобы стать полноценным DevOps инженером, вам потребуется хорошо разобраться в конфигурации инструментов управления вроде puppet или ansible. Здесь вам понадобится уметь работать с обеими версиями;
  • Если код вашей компании написан в Python 2, потребуется научиться с ним работать;
  • Если ваша команда разработчиков работает над проектом, который зависит от сторонних библиотек или программного обеспечения, что нельзя портировать в Python 3, тогда единственным возможным вариантом остается Python 2.

Какую версию Python использовать?

python

Вопросы по темам Python 2 vs. Python 3 на Stack Overflow

При сравнении версии 2 и 3, Python 3 безусловно является победителем. По большей части это связано с тем, что после 2020 года Python 2 не будет поддерживаться совсем. Массовое внедрение Python 3 — это четкое направление для будущего развития.

После рассмотрения всех за и против, в особенности прекращения поддержки Python 2, большинству новых разработчиков лучше остановиться на Python 3. Тем не менее, если задание требует возможностей Python 2, этот фактор может стать единственной веской причиной для использования версии 2.

Главные причины остановиться на Python 3.x:

  • Python 3 поддерживает современные методы, такие как AI, машинное обучение и наука о данных;
  • Python 3 поддерживается сообществом разработчиков Python. Можно легко получить помощь;
  • По сравнению с более ранними версиями проще дается изучение языка Python;
  • Предлагает мощный инструментарий и библиотеки;
  • Хорошо сочетается с другими языками.

История Python 2

  • Python 2.0 — Октябрь 16, 2000;
  • Python 2.1 — Апрель 17, 2001;
  • Python 2.2 — Декабрь 21, 2001;
  • Python 2.3 — Июль 29, 2003;
  • Python 2.4 — Ноябрь 30, 2004;
  • Python 2.5 — Сентябрь 19, 2006;
  • Python 2.6 — Октябрь 1, 2008;
  • Python 2.7 — Июль 3, 2010.

История Python 3

  • Python 3.0 — Декабрь 3, 2008;
  • Python 3.1 — Июнь 27, 2009;
  • Python 3.2 — Февраль 20, 2011;
  • Python 3.3 — Сентябрь 29, 2012;
  • Python 3.4 — Март 16, 2014;
  • Python 3.5 — Сентябрь 13, 2015;
  • Python 3.6 — Октябрь 2016;
  • Python 3.7 — Июнь 2018.
  • Python 3.8 — Октябрь 2019

На момент написание данной статьи, актуальная версия Python является 3.8.1 которая вышла 18 декабря 2019. Полный список релизов доступен тут: https://www.python.org/downloads/

Главные различия между Python 2 и Python 3

python 2 vs python 3

Основа сравнения Python 3 Python 2
Дата выпуска 2008 2000
Функция вывода print("hello") print "hello"
Деление целых чисел При делении целых чисел результатом является вещественное число. При делении целых чисел результатом является также целое число.
Юникод В Python 3 строки по умолчанию хранятся как Юникод (Unicode). Для хранения значения строки как Юникод (Unicode) требуется определить ее с «u».
Синтаксис Синтаксис проще и легче для понимания. Синтаксис в Python 2 несколько сложнее для понимания.
Правила очереди для сравнений В данной версии правила очереди для сравнений были упрощены. Правила очереди для сравнений достаточно сложны.
Итерация Введена новая функция range() для итераций. В Python 2 для итераций используется xrange().
Исключения Должны быть заключены в круглые скобки. Заключаются в примечаниях (notations).
Переменные Значение переменных не меняется. Глобальная переменная изменяется в цикле for при совпадении имён.
Обратная совместимость Портировать Python 2 на Python 3 довольно просто, однако надежность оставляет желать лучшего. Версия Python 3 обратно не совместима с Python 2.
Библиотеки В настоящее время многие разработчики создают библиотеки, которые можно использовать только с Python 3. Многие старые библиотеки, созданные с Python 2, являются не совместимыми с Python 3.

Подведем итоги:

  • Синтаксис Python 3 является более простым и понятным, тогда как синтаксис Python 2 сравнительно сложен для понимания;
  • По умолчанию для хранения строк в Python 3 используется Юникод (Unicode), в то время как в Python 2 необходимо определять строковое значение с помощью "u";
  • Значение переменных в Python 3 никогда не изменяется, тогда как в Python 2 значение глобальной переменной будет изменяться при использовании внутреннего цикла for;
  • Исключения Python 3 должны быть заключены в круглые скобки, а исключения Python 2 должны быть заключены в примечаниях (notations);
  • Правила очереди для сравнений в Python 3 упрощены по сравнению с Python 2;
  • Python 3 предлагает функцию range() для выполнения итераций, тогда как в Python 2 для итераций используется xrange().

Модуль __future__  Python

В Python 3.x были введены некоторые несовместимые с Python 2 ключевые слова и функции, которые можно импортировать с помощью встроенного модуля __future__ в Python 2.

Рекомендуется использовать __future__ для импорта, если вашему коду нужна поддержка Python 3.x. Например, если требуется поддержка деления целых чисел Python 3.x в Python 2, можно портировать его следующим образом:

Другие аспекты, что можно импортировать через модуль __future__, представлены ниже:

Аспект Опционален в Обязателен в Эффект
nested_scopes 2.1.0b1 2.2 PEP 227:
Статические области видимости
generators 2.2.0a1 2.3 PEP 255:
Простые генераторы
division 2.2.0a2 3.0 PEP 238:
Изменение оператора деления
absolute_import 2.5.0a1 3.0 PEP 328:
Импорты: Многострочные и Абсолютные/Относительные
with_statement 2.5.0a1 2.6 PEP 343:
Оператор “with” 
print_function 2.6.0a2 3.0 PEP 3105:
Делает print функцией
unicode_literals 2.6.0a2 3.0 PEP 3112:
Литералы байты в Python 3000

Сравнительные примеры кода Python 2 и Python 3

Python 2

Python 3

Функция print в Python 2 и Python 3

Изменение синтаксиса print является самым заметным изменением: оператор print из Python 2 был заменен функцией print() — теперь объект вывода обязательно должен быть заключен в скобки.

В Python 2 нет проблем с дополнительными скобками, однако в Python 3 при вызове функции print способом второй версии, выйдет ошибка SyntaxError.

Python 2

Вывод Python 2

Python 3

Вывод Python 3

Использование в Python 3 синтаксиса Python 2

Вывод Python 3

На заметку: Вышеуказанный вывод "Hello, World" через Python 2 выглядит вроде как «нормально». Однако, если поместить внутрь скобок несколько объектов, будет создан кортеж, ведь в Python 2 print является оператором, а не функцией вызова.

Вывод

Деление целых чисел в Python 2 и Python 3

С данным изменением стоит быть особенно осторожным при переносе или выполнении кода Python 3 в Python 2. Изменение поведения целочисленного деления часто остается незамеченным, так как оно не вызывает SyntaxError.

Таким образом, при написании кода Python 3 многие используют float(3)/2 или 3/2.0 вместо 3/2, что упрощает жизнь тем, кто работает в Python 2. В Python 2 также рекомендуется использовать from __future__ import division.

Python 2

Вывод Python 2

Python 3

Вывод Python 3

c
В Python 2 есть типы ASCII str(), отдельно unicode(), однако типа byte нет.

В Python 3 есть строки str Unicode (utf-8), а также 2 класса байтов: byte и bytearray.

Python 2

Python 3

Функция xrange() в Python 2

Использование довольно популярно в Python 2.x ввиду создания итерируемого объекта, то есть цикла for или включения в виде списка, множества или словаря. Поведение напоминало работу генератора, то есть «ленивое вычисление», однако здесь итерация xrange не является исчерпывающей, то есть вы можете перебирать ее бесконечно.

Благодаря «ленивому вычислению», преимущество обычного range() в том, что xrange() обычно быстрее, если вы итерировали только раз (в цикле for). Однако по сравнению с одноразовыми итерациями, не рекомендуется повторять итерацию множество раз, так как каждый раз итерация начинается с нуля.

В Python 3 была имплементирована range() вместо xrange(). Функция xrange() больше использоваться не может, вызывая в Python 3 ошибку NameError.

Python 2

Python 3

Метод __contains__ для объектов range в Python 3

Также стоит упомянуть, что в Python 3.х у range появился новый метод __contains__. Метод __contains__ может значительно ускорить поиск в range в Python 3.x для типов integer и Boolean.

На основании результатов timeit выше видно, что выполнение поиска было примерно в 60 000 раз быстрее, когда тип был integer, а не float. Однако, ввиду того, что в Python 2.x у range или xrange нет метода __contains__, скорость поиска для integer или float будет не сильно отличаться:

Ниже представлено своего рода подтверждение того, что метода __contain__ в Python 2.x и правда нет.

Разница в скорости между Python 2 и Python 3

Многие разработчики отмечают разницу в скорости между range() в Python 3 и xrange() в Python 2. Так как оба метода имплементируются одинаково разумно ожидать одинаковой скорости. Однако разница все же есть, и она обусловлена тем фактом, что Python 3 в общем и целом обычно выполняется медленнее, чем Python 2.

Вызов исключений в разных версиях Python

В то время, как Python 2 принимает старый и новый синтаксис исключений, Python 3 отказывается это делать. Если не заключить аргумент исключения в скобки, в Python 3 поднимается ошибка SyntaxError.

Python 2

Python 3

Правильный способ поднятия исключения в Python 3:

Обработка исключений в Python 2 и Python 3

Обработка исключений в Python 2 и Python 3 несколько отличается. В Python 3 в качестве ключевого слова нужно использовать "as".

Python 2

Python 3

Функция next() и метод .next() в Python

Так как next() (.next()) является довольной популярной функцией (методом), стоит упомянуть об еще одном изменении в синтаксисе, или скорее изменении в имплементации.

В то время, как в Python 2.7.5 можно использовать синтаксис как функции, так и метода, в Python 3 остается доступной только функция next(). При вызове метода .next() в Python 3 поднимается ошибка AttributeError.

Python 2

Python 3

Переменные цикла for и глобальная утечка пространства названий

Хорошая новость: в Python 3.х переменные цикла for больше не утекают в глобальную область видимости! Это связано с изменением в Python 3.х, которое описано в What’s New In Python 3.0 следующим образом:

«Списковые включения больше не поддерживают синтаксическую форму [... for var in item1, item2, ...]. Вместо этого нужно использовать [... for var in (item1, item2, ...)]. Также обратите внимание, что у списковых включений теперь другая семантика: они ближе к синтаксису выражения генератора внутри конструктора list(), и переменные контроля больше не просачиваются в окружающее пространство».

Python 2

Python 3

Сравнение неупорядоченных типов Python

Другое полезное изменение в Python 3 — в качестве предупреждения при попытке сравнения неупорядоченных типов поднимается исключение TypeError.

Python 2

Python 3

Парсинг входных данных пользователя с input()

К счастью, функция input() была исправлена в Python 3, таким образом позволяя хранить входные данные пользователя как объекты str. Во избежание опасного поведения в Python 2 при чтении в других типов, помимо string, нужно использовать raw_input().

Python 2

Python 3

Возвращение итерируемых объектов вместо списков

Как уже упоминалось в разделе о xrange, некоторые функции и методы в Python 3 теперь возвращают итерируемые объекты — вместо списков в Python 2.

Так как мы обычно итерируем их только один раз, это изменение имеет большой смысл для экономии памяти. Однако, в отличие от генераторов, также возможно, при необходимости, выполнять многократное повторение, но это не так эффективно.

А в тех случаях, когда действительно нужны объекты list, можно просто преобразовать итерируемый объект в список list с помощью функции list().

Python 2

Python 3

Другие популярные функции, которые не возвращают списки в Python 3:

  • zip()
  • map()
  • filter()
  • метод словаря .keys()
  • метод словаря .values()
  • метод словаря .items()

Банковское (бухгалтерское) округление Python

В Python 3 был принят стандартный способ округления десятичных дробей, когда он приводит к привязке (.5) к последним значащим цифрам. Теперь в Python 3 десятичные дроби округляются до ближайшего четного числа. Хотя это неудобно для переносимости кода, но это якобы лучший способ округления по сравнению с обычным округлением вверх, поскольку он позволяет избежать смещения в сторону больших чисел.

Python 2

Python 3

Рекомендации статей о Python 2 и Python 3

Далее представлен список неплохих статей о Python 2 и 3. Все тексты на английском.

Портирование на Python 3:

Плюсы и минусы Python 3: