Многие пользователи задаются вопросом, с какой версии Python следует начинать изучение данного языка. Зачастую новички останавливаются на версии, которая фигурирует в рассматриваемом ими учебном пособии.
Содержание статьи
- Что такое Python 2?
- Что такое Python 3?
- Что нужно знать о Python 2?
- Какую версию Python использовать?
- История Python 2
- История Python 3
- Главные различия между Python 2 и Python 3
- Модуль __future__ Python
- Сравнительные примеры кода Python 2 и Python 3
- Функция print в Python 2 и Python 3
- Деление целых чисел в Python 2 и Python 3
- Юникод в Python 2 и Python 3
- Функция xrange() в Python 2
- Метод __contains__ для объектов range в Python 3
- Разница в скорости между Python 2 и Python 3
- Вызов исключений в разных версиях Python
- Обработка исключений в Python 2 и Python 3
- Функция next() и метод .next() в Python
- Переменные цикла for и глобальная утечка пространства названий
- Сравнение неупорядоченных типов Python
- Парсинг входных данных пользователя с input()
- Возвращение итерируемых объектов вместо списков
- Банковское (бухгалтерское) округление Python
- Рекомендации статей о Python 2 и Python 3
Однако, как быть, если при создании нового проекта у вас есть выбор? Можно сказать, что если обе версии поддерживают библиотеки, которые вы планируете использовать, нет нужды особо волноваться. Тем не менее, будет не лишним взглянуть на основные различия между 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?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
В результате для любой организации, которая использовала версию Python 2.x, миграция проекта на 3.x требовала большого количества изменений. Эти изменения касаются не только проектов и приложений, но и всех библиотек, которые являются частью экосистемы Python.
Что нужно знать о Python 2?
Тренды Google в отношении Python 2 vs. Python 3
Хотя на сегодняшний день Python 2 является уже устаревшей версией с открытым кодом, на определенные моменты стоит обратить особое внимание:
- Для того чтобы стать полноценным DevOps инженером, вам потребуется хорошо разобраться в конфигурации инструментов управления вроде puppet или ansible. Здесь вам понадобится уметь работать с обеими версиями;
- Если код вашей компании написан в Python 2, потребуется научиться с ним работать;
- Если ваша команда разработчиков работает над проектом, который зависит от сторонних библиотек или программного обеспечения, что нельзя портировать в Python 3, тогда единственным возможным вариантом остается Python 2.
Какую версию 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 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, можно портировать его следующим образом:
1 |
from __future__ import division |
Другие аспекты, что можно импортировать через модуль __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
1 2 3 4 5 |
def main(): print "Hello World!" if __name__== "__main__": main() |
Python 3
1 2 3 4 5 |
def main(): print("Hello World!") if __name__== "__main__": main() |
Функция print в Python 2 и Python 3
Изменение синтаксиса print
является самым заметным изменением: оператор print
из Python 2 был заменен функцией print()
— теперь объект вывода обязательно должен быть заключен в скобки.
В Python 2 нет проблем с дополнительными скобками, однако в Python 3 при вызове функции print способом второй версии, выйдет ошибка SyntaxError.
Python 2
1 2 3 4 |
print 'Python', python_version() print 'Hello, World!' print('Hello, World!') print "text", ; print 'print more text on the same line' |
Вывод Python 2
1 2 3 4 |
Python 2.7.6 Hello, World! Hello, World! text print more text on the same line |
Python 3
1 2 3 4 5 |
print('Python', python_version()) print('Hello, World!') print("some text,", end="") print(' print more text on the same line') |
Вывод Python 3
1 2 3 |
Python 3.8.1 Hello, World! some text, print more text on the same line |
Использование в Python 3 синтаксиса Python 2
1 |
print 'Hello, World!' |
Вывод Python 3
1 2 3 4 |
File "<ipython-input-3-139a7c5835bd>", line 1 print 'Hello, World!' ^ SyntaxError: invalid syntax |
На заметку: Вышеуказанный вывод
"Hello, World"
через Python 2 выглядит вроде как «нормально». Однако, если поместить внутрь скобок несколько объектов, будет создан кортеж, ведь в Python 2
1 2 3 |
print 'Python', python_version() print('a', 'b') print 'a', 'b' |
Вывод
1 2 3 |
Python 2.7.6 ('a', 'b') a b |
Деление целых чисел в 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
1 2 3 4 5 |
print 'Python', python_version() print '3 / 2 =', 3 / 2 print '3 // 2 =', 3 // 2 print '3 / 2.0 =', 3 / 2.0 print '3 // 2.0 =', 3 // 2.0 |
Вывод Python 2
1 2 3 4 5 |
Python 2.7.6 3 / 2 = 1 3 // 2 = 1 3 / 2.0 = 1.5 3 // 2.0 = 1.0 |
Python 3
1 2 3 4 5 |
print('Python', python_version()) print('3 / 2 =', 3 / 2) print('3 // 2 =', 3 // 2) print('3 / 2.0 =', 3 / 2.0) print('3 // 2.0 =', 3 // 2.0) |
Вывод Python 3
1 2 3 4 5 |
Python 3.8.1 3 / 2 = 1.5 3 // 2 = 1 3 / 2.0 = 1.5 3 // 2.0 = 1.0 |
c
В Python 2 есть типы ASCII str()
, отдельно unicode()
, однако типа byte
нет.
В Python 3 есть строки str
Unicode (utf-8), а также 2 класса байтов: byte
и bytearray
.
Python 2
1 |
print 'Python', python_version() |
1 |
Python 2.7.6 |
1 |
print type(unicode('this is like a python3 str type')) |
1 |
<type 'unicode'> |
1 |
print type(b'byte type does not exist') |
1 |
<type 'str'> |
1 |
print 'they are really' + b' the same' |
1 |
they are really the same |
1 |
print type(bytearray(b'bytearray oddly does exist though')) |
1 |
<type 'bytearray'> |
Python 3
1 2 |
print('Python', python_version()) print('strings are now utf-8 \u03BCnico\u0394é!') |
1 2 |
Python 3.8.1 strings are now utf-8 μnicoΔé! |
1 2 |
print('Python', python_version(), end="") print(' has', type(b' bytes for storing data')) |
1 |
Python 3.8.1 has <class 'bytes'> |
1 2 |
print('and Python', python_version(), end="") print(' also has', type(bytearray(b'bytearrays'))) |
1 |
and Python 3.8.1 also has <class 'bytearray'> |
1 |
'note that we cannot add a string' + b'bytes for data' |
1 2 3 4 5 6 7 8 |
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-13-d3e8942ccf81> in <module>() ----> 1 'note that we cannot add a string' + b'bytes for data' TypeError: Can't convert 'bytes' object to str implicitly |
Функция xrange() в Python 2
Использование довольно популярно в Python 2.x ввиду создания итерируемого объекта, то есть цикла for или включения в виде списка, множества или словаря. Поведение напоминало работу генератора, то есть «ленивое вычисление», однако здесь итерация xrange не является исчерпывающей, то есть вы можете перебирать ее бесконечно.
Благодаря «ленивому вычислению», преимущество обычного range()
в том, что xrange()
обычно быстрее, если вы итерировали только раз (в цикле for
). Однако по сравнению с одноразовыми итерациями, не рекомендуется повторять итерацию множество раз, так как каждый раз итерация начинается с нуля.
В Python 3 была имплементирована range()
вместо xrange()
. Функция xrange()
больше использоваться не может, вызывая в Python 3 ошибку NameError
.
1 2 3 4 5 6 7 8 9 10 |
import timeit n = 10000 def test_range(n): return for i in range(n): pass def test_xrange(n): for i in xrange(n): pass |
Python 2
1 2 3 4 5 6 7 8 |
print 'Python', python_version() print '\ntiming range()' %timeit test_range(n) print '\n\ntiming xrange()' %timeit test_xrange(n) |
1 2 3 4 5 6 7 8 |
Python 2.7.6 timing range() 1000 loops, best of 3: 433 µs per loop timing xrange() 1000 loops, best of 3: 350 µs per loop |
Python 3
1 2 3 4 |
print('Python', python_version()) print('\ntiming range()') %timeit test_range(n) |
1 2 3 4 |
Python 3.8.1 timing range() 1000 loops, best of 3: 520 µs per loop |
1 |
print(xrange(10)) |
1 2 3 4 5 6 7 8 |
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-5-5d8f9b79ea70> in <module>() ----> 1 print(xrange(10)) NameError: name 'xrange' is not defined |
Метод __contains__ для объектов range в Python 3
Также стоит упомянуть, что в Python 3.х у range появился новый метод __contains__
. Метод __contains__
может значительно ускорить поиск в range
в Python 3.x для типов integer и Boolean.
1 |
x = 10000000 |
1 2 |
def val_in_range(x, val): return val in range(x) |
1 2 |
def val_in_xrange(x, val): return val in xrange(x) |
1 2 3 4 5 6 |
print('Python', python_version()) assert(val_in_range(x, x/2) == True) assert(val_in_range(x, x//2) == True) %timeit val_in_range(x, x/2) %timeit val_in_range(x, x//2) |
1 2 3 |
Python 3.8.1 1 loops, best of 3: 742 ms per loop 1000000 loops, best of 3: 1.19 µs per loop |
На основании результатов timeit выше видно, что выполнение поиска было примерно в 60 000 раз быстрее, когда тип был integer, а не float. Однако, ввиду того, что в Python 2.x у range
или xrange
нет метода __contains__
, скорость поиска для integer или float будет не сильно отличаться:
1 2 3 4 5 6 7 8 9 10 11 12 |
print 'Python', python_version() assert(val_in_xrange(x, x/2.0) == True) assert(val_in_xrange(x, x/2) == True) assert(val_in_range(x, x/2) == True) assert(val_in_range(x, x//2) == True) %timeit val_in_xrange(x, x/2.0) %timeit val_in_xrange(x, x/2) %timeit val_in_range(x, x/2.0) %timeit val_in_range(x, x/2) |
1 2 3 4 5 |
Python 2.7.6 1 loops, best of 3: 285 ms per loop 1 loops, best of 3: 179 ms per loop 1 loops, best of 3: 658 ms per loop 1 loops, best of 3: 556 ms per loop |
Ниже представлено своего рода подтверждение того, что метода __contain__ в Python 2.x и правда нет.
1 2 |
print('Python', python_version()) range.__contains__ |
1 2 |
Python 3.8.1 <slot wrapper '__contains__' of 'range' objects> |
1 2 |
print 'Python', python_version() range.__contains__ |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Python 2.7.6 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-7-05327350dafb> in <module>() 1 print 'Python', python_version() ----> 2 range.__contains__ AttributeError: 'builtin_function_or_method' object has no attribute '__contains__' |
1 2 |
print 'Python', python_version() xrange.__contains__ |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Python 2.7.6 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-8-7d1a71bfee8e> in <module>() 1 print 'Python', python_version() ----> 2 xrange.__contains__ AttributeError: type object 'xrange' has no attribute '__contains__' |
Разница в скорости между Python 2 и Python 3
Многие разработчики отмечают разницу в скорости между range()
в Python 3 и xrange()
в Python 2. Так как оба метода имплементируются одинаково разумно ожидать одинаковой скорости. Однако разница все же есть, и она обусловлена тем фактом, что Python 3 в общем и целом обычно выполняется медленнее, чем Python 2.
1 2 3 4 5 |
def test_while(): i = 0 while i < 20000: i += 1 return |
1 2 |
print('Python', python_version()) %timeit test_while() |
1 2 |
Python 3.8.1 100 loops, best of 3: 2.68 ms per loop |
1 2 |
print 'Python', python_version() %timeit test_while() |
1 2 |
Python 2.7.6 1000 loops, best of 3: 1.72 ms per loop |
Вызов исключений в разных версиях Python
В то время, как Python 2 принимает старый и новый синтаксис исключений, Python 3 отказывается это делать. Если не заключить аргумент исключения в скобки, в Python 3 поднимается ошибка SyntaxError
.
Python 2
1 |
print 'Python', python_version() |
1 |
Python 2.7.6 |
1 |
raise IOError, "file error" |
1 2 3 4 5 6 7 8 |
--------------------------------------------------------------------------- IOError Traceback (most recent call last) <ipython-input-8-25f049caebb0> in <module>() ----> 1 raise IOError, "file error" IOError: file error |
1 |
raise IOError("file error") |
1 2 3 4 5 6 7 8 |
--------------------------------------------------------------------------- IOError Traceback (most recent call last) <ipython-input-9-6f1c43f525b2> in <module>() ----> 1 raise IOError("file error") IOError: file error |
Python 3
1 |
print('Python', python_version()) |
1 |
Python 3.8.1 |
1 |
raise IOError, "file error" |
1 2 3 4 |
File "<ipython-input-10-25f049caebb0>", line 1 raise IOError, "file error" ^ SyntaxError: invalid syntax |
Правильный способ поднятия исключения в Python 3:
1 2 |
print('Python', python_version()) raise IOError("file error") |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Python 3.4.1 --------------------------------------------------------------------------- OSError Traceback (most recent call last) <ipython-input-11-c350544d15da> in <module>() 1 print('Python', python_version()) ----> 2 raise IOError("file error") OSError: file error |
Обработка исключений в Python 2 и Python 3
Обработка исключений в Python 2 и Python 3 несколько отличается. В Python 3 в качестве ключевого слова нужно использовать "as"
.
Python 2
1 2 3 4 5 |
print 'Python', python_version() try: let_us_cause_a_NameError except NameError, err: print err, '--> our error message' |
1 2 |
Python 2.7.6 name 'let_us_cause_a_NameError' is not defined --> our error message |
Python 3
1 2 3 4 5 |
print('Python', python_version()) try: let_us_cause_a_NameError except NameError as err: print(err, '--> our error message') |
1 2 |
Python 3.8.1 name 'let_us_cause_a_NameError' is not defined --> our error message |
Функция next() и метод .next() в Python
Так как next()
(.next()
) является довольной популярной функцией (методом), стоит упомянуть об еще одном изменении в синтаксисе, или скорее изменении в имплементации.
В то время, как в Python 2.7.5 можно использовать синтаксис как функции, так и метода, в Python 3 остается доступной только функция next()
. При вызове метода .next()
в Python 3 поднимается ошибка AttributeError
.
Python 2
1 2 3 4 5 6 |
print 'Python', python_version() my_generator = (letter for letter in 'abcdefg') next(my_generator) my_generator.next() |
1 2 3 |
Python 2.7.6 'b' |
Python 3
1 2 3 4 5 |
print('Python', python_version()) my_generator = (letter for letter in 'abcdefg') next(my_generator) |
1 2 3 |
Python 3.8.1 'a' |
1 |
my_generator.next() |
1 2 3 4 5 6 7 8 |
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-14-125f388bb61b> in <module>() ----> 1 my_generator.next() AttributeError: 'generator' object has no attribute 'next' |
Переменные цикла 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
1 2 3 4 5 6 7 8 |
print 'Python', python_version() i = 1 print 'before: i =', i print 'comprehension: ', [i for i in range(5)] print 'after: i =', i |
1 2 3 4 |
Python 2.7.6 before: i = 1 comprehension: [0, 1, 2, 3, 4] after: i = 4 |
Python 3
1 2 3 4 5 6 7 8 |
print('Python', python_version()) i = 1 print('before: i =', i) print('comprehension:', [i for i in range(5)]) print('after: i =', i) |
1 2 3 4 |
Python 3.8.1 before: i = 1 comprehension: [0, 1, 2, 3, 4] after: i = 1 |
Сравнение неупорядоченных типов Python
Другое полезное изменение в Python 3 — в качестве предупреждения при попытке сравнения неупорядоченных типов поднимается исключение TypeError
.
Python 2
1 2 3 4 |
print 'Python', python_version() print "[1, 2] > 'foo' = ", [1, 2] > 'foo' print "(1, 2) > 'foo' = ", (1, 2) > 'foo' print "[1, 2] > (1, 2) = ", [1, 2] > (1, 2) |
1 2 3 4 |
Python 2.7.6 [1, 2] > 'foo' = False (1, 2) > 'foo' = True [1, 2] > (1, 2) = False |
Python 3
1 2 3 4 |
print('Python', python_version()) print("[1, 2] > 'foo' = ", [1, 2] > 'foo') print("(1, 2) > 'foo' = ", (1, 2) > 'foo') print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Python 3.8.1 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-16-a9031729f4a0> in <module>() 1 print('Python', python_version()) ----> 2 print("[1, 2] > 'foo' = ", [1, 2] > 'foo') 3 print("(1, 2) > 'foo' = ", (1, 2) > 'foo') 4 print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2)) TypeError: unorderable types: list() > str() |
Парсинг входных данных пользователя с input()
К счастью, функция input()
была исправлена в Python 3, таким образом позволяя хранить входные данные пользователя как объекты str
. Во избежание опасного поведения в Python 2 при чтении в других типов, помимо string, нужно использовать raw_input()
.
Python 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Python 2.7.6 [GCC 4.0.1 (Apple Inc. build 5493)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> my_input = input('enter a number: ') enter a number: 123 >>> type(my_input) <type 'int'> >>> my_input = raw_input('enter a number: ') enter a number: 123 >>> type(my_input) <type 'str'> |
Python 3
1 2 3 4 5 6 7 8 9 10 |
Python 3.4.1 [GCC 4.2.1 (Apple Inc. build 5577)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> my_input = input('enter a number: ') enter a number: 123 >>> type(my_input) <class 'str'> |
Возвращение итерируемых объектов вместо списков
Как уже упоминалось в разделе о xrange
, некоторые функции и методы в Python 3 теперь возвращают итерируемые объекты — вместо списков в Python 2.
Так как мы обычно итерируем их только один раз, это изменение имеет большой смысл для экономии памяти. Однако, в отличие от генераторов, также возможно, при необходимости, выполнять многократное повторение, но это не так эффективно.
А в тех случаях, когда действительно нужны объекты list
, можно просто преобразовать итерируемый объект в список list
с помощью функции list()
.
Python 2
1 2 3 4 |
print 'Python', python_version() print range(3) print type(range(3)) |
1 2 3 |
Python 2.7.6 [0, 1, 2] <type 'list'> |
Python 3
1 2 3 4 5 |
print('Python', python_version()) print(range(3)) print(type(range(3))) print(list(range(3))) |
1 2 3 4 |
Python 3.8.1 range(0, 3) <class 'range'> [0, 1, 2] |
Другие популярные функции, которые не возвращают списки в Python 3:
zip()
map()
filter()
- метод словаря
.keys()
- метод словаря
.values()
- метод словаря
.items()
Банковское (бухгалтерское) округление Python
В Python 3 был принят стандартный способ округления десятичных дробей, когда он приводит к привязке (.5) к последним значащим цифрам. Теперь в Python 3 десятичные дроби округляются до ближайшего четного числа. Хотя это неудобно для переносимости кода, но это якобы лучший способ округления по сравнению с обычным округлением вверх, поскольку он позволяет избежать смещения в сторону больших чисел.
Python 2
1 |
print 'Python', python_version() |
1 |
Python 2.7.12 |
1 |
round(15.5) |
1 |
16.0 |
1 |
round(16.5) |
1 |
17.0 |
Python 3
1 |
print('Python', python_version()) |
1 |
Python 3.8.1 |
1 |
round(15.5) |
1 |
16 |
1 |
round(16.5) |
1 |
16 |
Рекомендации статей о Python 2 и Python 3
Далее представлен список неплохих статей о Python 2 и 3. Все тексты на английском.
Портирование на Python 3:
- Что выбрать во время разработки — Python 2 или Python 3?
- Новое в Python 3.0
- Портирование на Python 3
- Портирование кода Python 2 на Python 3
- Как поддержать Python 3
Плюсы и минусы Python 3:
- 10 отличных аспектов Python, которые стали доступны после обновления
- Все важное об Юникоде в Python 3
- Python 3 возрождает Python
- Python 3 в порядке
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»