Книга: PyNEng
Назад: Дополнительные материалы
Дальше: Продолжение обучения

Отличия Python 2.7 и Python 3

Отличия Python 2.7 и Python 3.6

На данный момент есть две версии книги: для и Python 3.6. Чтобы облегчить переход с версии 2.7 на 3.6, тут перечислены отличия между этими версиями книги.

Кроме отличий, которые сделаны из-за изменений в Python 3, в книге также .

Со временем, эти обновления будут перенесены и в книгу по Python 2.7

В Python 2.7 было два типа строк: str и unicode:

In [1]: line = 'test'  In [2]: line2 = u'тест' 

В Python 3 строка - это тип str, но, кроме этого, в Python 3 появился тип bytes:

In [3]: line = 'тест'  In [4]: line.encode('utf-8') Out[4]: b'\xd1\x82\xd0\xb5\xd1\x81\xd1\x82'  In [5]: byte_str = b'test' 

В Python 2.7 print был оператором:

In [6]: print 1, 'test' 1 test 

В Python 3 :

In [7]: print(1, 'test') 1 test 

В Python 2.7 можно брать аргументы в скобки, но от этого print не становится функцией и, кроме того, print возвращает другой результат (кортеж):

In [8]: print(1, 'test') (1, 'test') 

В Python 3, использование синтаксиса Python 2.7 приведет к ошибке:

In [9]: print 1, 'test'   File "<ipython-input-2-328abb6b105d>", line 1     print 1, 'test'           ^ SyntaxError: Missing parentheses in call to 'print' 

В Python 2.7 для получения информации от пользователя в виде строки использовалась функция raw_input:

In [10]: number = raw_input('Number: ') Number: 55  In [11]: number Out[11]: '55' 

В Python 3 используется input:

In [12]: number = input('Number: ') Number: 55  In [13]: number Out[13]: '55' 

В Python 2.7 были две функции

  • range - возвращает список
  • xrange - возвращает итератор

Пример range и xrange в Python 2.7:

In [14]: range(5) Out[14]: [0, 1, 2, 3, 4]  In [15]: xrange(5) Out[15]: xrange(5)  In [16]: list(xrange(5)) Out[16]: [0, 1, 2, 3, 4] 

В Python 3 есть только функция range, и она возвращает итератор:

In [17]: range(5) Out[17]: range(0, 5)  In [18]: list(range(5)) Out[18]: [0, 1, 2, 3, 4] 

Несколько изменений произошло в методах словарей.

dict.keys(), values(), items()

Методы keys(), values(), items() в Python 3 возвращают "views" вместо списков. Особенность view заключается в том, что они меняются вместе с изменением словаря. И фактически они лишь дают способ посмотреть на соответствующие объекты, но не создают их копию.

В Python 3 нет методов:

  • viewitems, viewkeys, viewvalues
  • iteritems, iterkeys, itervalues

Для сравнения, методы словаря в Python 2.7:

In [19]: d = {1:100, 2:200, 3:300}  In [20]: d.     d.clear      d.get        d.iteritems  d.keys       d.setdefault d.viewitems     d.copy       d.has_key    d.iterkeys   d.pop        d.update     d.viewkeys     d.fromkeys   d.items      d.itervalues d.popitem    d.values     d.viewvalues 

И в Python 3:

In [21]: d = {1:100, 2:200, 3:300}  In [22]: d.            clear()      get()        pop()        update()            copy()       items()      popitem()    values()            fromkeys()   keys()       setdefault() 

В Python 3 появилась возможность использовать * при распаковке переменных:

In [23]: a, *b, c = [1,2,3,4,5]  In [24]: a Out[24]: 1  In [25]: b Out[25]: [2, 3, 4]  In [26]: c Out[26]: 5 

В Python 2.7 этот синтаксис не поддерживается:

In [27]: a, *b, c = [1,2,3,4,5]   File "<ipython-input-10-e3f57143ffb4>", line 1     a, *b, c = [1,2,3,4,5]        ^ SyntaxError: invalid syntax 

В Python 2.7 map, filter и zip возвращали список:

In [28]: map(str, [1,2,3,4,5]) Out[28]: ['1', '2', '3', '4', '5']  In [29]: filter(lambda x: x>3, [1,2,3,4,5]) Out[29]: [4, 5]  In [30]: zip([1,2,3], [100,200,300]) Out[30]: [(1, 100), (2, 200), (3, 300)] 

В Python 3 они возвращают итератор:

In [31]: map(str, [1,2,3,4,5]) Out[31]: <map at 0xb4ee3fec>  In [32]: filter(lambda x: x>3, [1,2,3,4,5]) Out[32]: <filter at 0xb448c68c>  In [33]: zip([1,2,3], [100,200,300]) Out[33]: <zip at 0xb4efc1ec> 

В версии Python 3.5 в модуле subprocess появилась новая функция - run. Она предоставляет более удобный интерфейс для работы с модулем и получения вывода команд.

Соответственно, вместо функций call и check_output используется функция run. Но функции call и check_output остались.

Jinja2

В модуле Jinja2 больше не нужно использовать такой код, так как кодировка по умолчанию и так utf-8:

import sys      reload(sys)        sys.setdefaultencoding('utf-8') 

В самих шаблонах, как и в Python, изменились методы словарей. Тут, аналогично, вместо iteritems надо использовать items.

Модули pexpect, telnetlib, paramiko

Модули pexpect, telnetlib, paramiko отправляют и получают байты, поэтому надо делать encode/decode соответственно.

В netmiko эта конвертация выполняется автоматически.

Мелочи

  • Название модуля Queue сменилось на queue
  • С версии Python 3.6 объект csv.DictReader возвращает OrderedDict вместо обычного словаря.

Дополнительная информация

Ниже приведены ссылки на ресурсы с информацией об изменениях в Python 3.

Документация:

Статьи:

Назад: Дополнительные материалы
Дальше: Продолжение обучения