Что нового в Python 3.0

Автор

Гвидо ван Россум

В этой статье рассказывается о новых возможностях Python 3.0 по сравнению с 2.6. Python 3.0, также известный как «Python 3000» или «Py3K», является первым преднамеренно обратно несовместимым выпуском Python. Python 3.0 был выпущен 3 декабря 2008 года. В нем больше изменений, чем в обычном релизе, и больше изменений, которые важны для всех пользователей Python. Тем не менее, ознакомившись с изменениями, вы обнаружите, что Python на самом деле изменился не так уж сильно - по большому счету, мы в основном исправляем известные раздражители и недостатки, а также удаляем много старого мусора.

В этой статье не делается попытка дать полное описание всех новых возможностей, а вместо этого делается попытка дать удобный обзор. За полной информацией следует обращаться к документации по Python 3.0 и/или к многочисленным PEP, на которые есть ссылки в тексте. Если вы хотите понять полную реализацию и обоснование дизайна конкретной функции, PEP обычно содержат больше деталей, чем обычная документация; но учтите, что PEP обычно не обновляются после того, как функция полностью реализована.

Из-за нехватки времени этот документ не является таким полным, каким он должен был бы быть. Как всегда для нового выпуска, файл Misc/NEWS в исходном дистрибутиве содержит множество подробной информации о каждой мелочи, которая была изменена.

Общие камни преткновения

В этом разделе перечислены те немногие изменения, которые, скорее всего, поставят вас в тупик, если вы привыкли к Python 2.5.

Представления и итераторы вместо списков

Некоторые известные API больше не возвращают списки:

  • Методы dict dict.keys(), dict.items() и dict.values() возвращают «представления» вместо списков. Например, это больше не работает: k = d.keys(); k.sort(). Вместо этого используйте k = sorted(d) (это работает и в Python 2.5 и так же эффективно).

  • Также больше не поддерживаются методы dict.iterkeys(), dict.iteritems() и dict.itervalues().

  • map() и filter() возвращают итераторы. Если вам действительно нужен список, а входные последовательности имеют одинаковую длину, быстрое решение - обернуть map() в list(), например list(map(...)), но лучшим решением часто является использование понимания списка (особенно если в исходном коде используется lambda) или переписывание кода так, чтобы он вообще не нуждался в списке. Особую сложность представляет map(), вызываемый для побочных эффектов функции; правильным преобразованием является использование обычного цикла for (поскольку создание списка было бы просто расточительным).

    Если входные последовательности не одинаковой длины, map() остановится на окончании самой короткой из последовательностей. Для полной совместимости с map() из Python 2.x, также оберните последовательности в itertools.zip_longest(), например, map(func, *sequences) станет list(map(func, itertools.zip_longest(*sequences))).

  • range() теперь ведет себя так же, как раньше xrange(), за исключением того, что работает со значениями произвольного размера. Последнего больше не существует.

  • zip() теперь возвращает итератор.

Сравнение заказов

В Python 3.0 упрощены правила упорядочивания сравнений:

  • Операторы сравнения порядка (<, <=, >=, >) вызывают исключение TypeError, когда операнды не имеют значимого естественного порядка. Таким образом, выражения типа 1 < '', 0 > None или len <= len больше не действительны, а, например, None < None вызывает TypeError вместо возврата False. Следствием этого является то, что сортировка неоднородного списка больше не имеет смысла - все элементы должны быть сравнимы друг с другом. Обратите внимание, что это не относится к операторам == и !=: объекты разных несравнимых типов всегда сравниваются неравноценно друг с другом.

  • builtin.sorted() и list.sort() больше не принимают аргумент cmp, предоставляющий функцию сравнения. Вместо этого используйте аргумент key. N.B. Аргументы key и reverse теперь «только для ключевых слов».

  • Функцию cmp() следует считать исчезнувшей, а специальный метод __cmp__() больше не поддерживается. Используйте __lt__() для сортировки, __eq__() с __hash__(), и другие богатые сравнения по мере необходимости. (Если вам действительно нужна функциональность cmp(), вы можете использовать выражение (a > b) - (a < b) как эквивалент для cmp(a, b)).

Целые числа

  • PEP 237: По сути, long переименован в int. То есть, существует только один встроенный интегральный тип, названный int; но он ведет себя в основном как старый тип long.

  • PEP 238: Выражение типа 1/2 возвращает плавающее число. Используйте 1//2, чтобы получить усечение. (Последний синтаксис существует уже много лет, по крайней мере, начиная с Python 2.2).

  • Константа sys.maxint была удалена, поскольку больше не существует ограничения на значение целых чисел. Однако sys.maxsize может использоваться как целое число, большее, чем любой практический индекс списка или строки. Оно соответствует «естественному» размеру целого числа в реализации и обычно совпадает с sys.maxint в предыдущих выпусках на той же платформе (при условии одинаковых опций сборки).

  • Длинное целое число repr() больше не включает завершающий символ L, поэтому код, который безоговорочно удаляет этот символ, вместо него отрезает последнюю цифру. (Вместо этого используйте str()).

  • Восьмеричные литералы больше не имеют форму 0720; вместо них используется 0o720.

Текст против данных вместо Юникода против 8-бита

Все, что вы думали, что знаете о двоичных данных и Unicode, изменилось.

  • Python 3.0 использует понятия текст и (двоичные) данные вместо строк Unicode и 8-битных строк. Весь текст является Юникодом; однако кодированный Юникод представлен в виде двоичных данных. Для хранения текста используется тип str, для хранения данных - bytes. Самое большое отличие от ситуации в версии 2.x заключается в том, что любая попытка смешать текст и данные в Python 3.0 приводит к появлению TypeError, тогда как если бы вы смешивали Unicode и 8-битные строки в Python 2.x, это сработало бы, если бы 8-битная строка содержала только 7-битные (ASCII) байты, но вы бы получили UnicodeDecodeError, если бы она содержала не-ASCII значения. Это специфическое для значений поведение вызывало множество грустных лиц на протяжении многих лет.

  • Вследствие этого изменения в философии практически весь код, использующий Unicode, кодировки или двоичные данные, скорее всего, должен измениться. Изменения к лучшему, так как в мире 2.x было множество ошибок, связанных со смешиванием кодированного и некодированного текста. Чтобы быть готовым в Python 2.x, начните использовать unicode для всего некодированного текста и str только для двоичных или кодированных данных. Тогда инструмент 2to3 сделает за вас большую часть работы.

  • Вы больше не можете использовать литералы u"..." для текста Unicode. Однако вы должны использовать литералы b"..." для двоичных данных.

  • Поскольку типы str и bytes нельзя смешивать, вы всегда должны явно конвертировать между ними. Используйте str.encode() для перехода от str к bytes, а bytes.decode() для перехода от bytes к str. Вы также можете использовать bytes(s, encoding=...) и str(b, encoding=...) соответственно.

  • Как и str, тип bytes является неизменяемым. Существует отдельный изменяемый тип для хранения буферизованных двоичных данных, bytearray. Почти все API, которые принимают bytes, также принимают bytearray. Мутабельный API основан на collections.MutableSequence.

  • Все обратные косые черты в необработанных строковых литералах интерпретируются буквально. Это означает, что эскейпы '\U' и '\u' в необработанных строках не обрабатываются специальным образом. Например, r'\u20ac' - это строка из 6 символов в Python 3.0, тогда как в 2.6 ur'\u20ac' был единственным символом «евро». (Конечно, это изменение затрагивает только необработанные строковые литералы; в Python 3.0 символом евро является '\u20ac').

  • Встроенный абстрактный тип basestring был удален. Вместо него используйте str. Типы str и bytes не имеют достаточно общей функциональности, чтобы требовать общего базового класса. Инструмент 2to3 (см. ниже) заменяет каждое вхождение basestring на str.

  • Файлы, открытые как текстовые (все еще режим по умолчанию для open()), всегда используют кодировку для отображения между строками (в памяти) и байтами (на диске). Бинарные файлы (открытые с помощью b в аргументе mode) всегда используют байты в памяти. Это означает, что если файл открыт с использованием неправильного режима или кодировки, ввод-вывод, скорее всего, будет громко завершен, вместо того чтобы тихо выдать неверные данные. Это также означает, что даже пользователям Unix придется указывать правильный режим (текстовый или двоичный) при открытии файла. Существует зависящая от платформы кодировка по умолчанию, которая на Unixy платформах может быть установлена с помощью переменной окружения LANG (а иногда и с помощью некоторых других специфических для платформы переменных окружения, связанных с локалью). Во многих случаях, но не во всех, системное значение по умолчанию - UTF-8; вы никогда не должны полагаться на это значение. Любое приложение, читающее или записывающее больше, чем чистый ASCII текст, должно иметь возможность переопределить кодировку. Больше нет необходимости использовать потоки с поддержкой кодировки в модуле codecs.

  • Начальные значения sys.stdin, sys.stdout и sys.stderr теперь являются текстовыми файлами только с уникодом (т.е. являются экземплярами io.TextIOBase). Чтобы читать и записывать байтовые данные с помощью этих потоков, необходимо использовать их атрибут io.TextIOBase.buffer.

  • Имена файлов передаются в API и возвращаются из них в виде строк (Unicode). Это может вызвать проблемы, связанные с конкретной платформой, поскольку на некоторых платформах имена файлов представляют собой произвольные байтовые строки. (С другой стороны, в Windows имена файлов хранятся как Unicode). В качестве обходного пути большинство API (например, open() и многие функции в модуле os), которые принимают имена файлов, принимают объекты bytes, а также строки, а некоторые API имеют возможность запросить возвращаемое значение bytes. Так, os.listdir() возвращает список экземпляров bytes, если аргумент является экземпляром bytes, а os.getcwdb() возвращает текущий рабочий каталог в виде экземпляра bytes. Обратите внимание, что когда os.listdir() возвращает список строк, имена файлов, которые не могут быть правильно декодированы, опускаются вместо того, чтобы выдать ошибку UnicodeError.

  • Некоторые системные API, такие как os.environ и sys.argv, также могут создавать проблемы, когда байты, предоставляемые системой, не могут быть интерпретированы с использованием кодировки по умолчанию. Установка переменной LANG и повторный запуск программы, вероятно, является лучшим подходом.

  • PEP 3138: repr() в строке больше не экранирует символы, не являющиеся символами ASCII. Однако он по-прежнему экранирует управляющие символы и точки кода с непечатаемым статусом в стандарте Unicode.

  • PEP 3120: Кодировка источника по умолчанию теперь UTF-8.

  • PEP 3131: Теперь в идентификаторах разрешены не ASCII-буквы. (Однако стандартная библиотека остается только ASCII, за исключением имен участников в комментариях).

  • Модули StringIO и cStringIO исчезли. Вместо них импортируйте модуль io и используйте io.StringIO или io.BytesIO для текста и данных соответственно.

  • См. также Юникод HOWTO, который был обновлен для Python 3.0.

Обзор изменений синтаксиса

В этом разделе дается краткий обзор всех синтаксических изменений в Python 3.0.

Новый синтаксис

  • PEP 3107: Аннотации аргументов и возвращаемого значения функции. Это стандартизированный способ аннотирования параметров и возвращаемого значения функции. К таким аннотациям не прилагается никакой семантики, кроме того, что они могут быть проанализированы во время выполнения с помощью атрибута __annotations__. Цель состоит в том, чтобы поощрять эксперименты с использованием метаклассов, декораторов или фреймворков.

  • PEP 3102: Аргументы только для ключевых слов. Именованные параметры, встречающиеся после *args в списке параметров, должны быть указаны с использованием синтаксиса ключевого слова в вызове. Вы также можете использовать голую строку * в списке параметров, чтобы указать, что вы не принимаете список аргументов переменной длины, но у вас есть аргументы только с ключевыми словами.

  • После списка базовых классов в определении класса допускаются аргументы с ключевыми словами. Это используется новым соглашением для указания метакласса (см. следующий раздел), но может использоваться и для других целей, если метакласс поддерживает это.

  • PEP 3104: nonlocal. С помощью nonlocal x теперь можно присваивать непосредственно переменной во внешней (но неглобальной) области видимости. nonlocal - это новое зарезервированное слово.

  • PEP 3132: Расширенная распаковка итерабельных функций. Теперь вы можете писать такие вещи, как a, b, *rest = some_sequence. И даже *rest, a = stuff. Объект rest всегда является (возможно пустым) списком; правая часть может быть любой итерируемой. Пример:

    (a, *rest, b) = range(5)
    

    Это устанавливает a в 0, b в 4, а rest в [1, 2, 3].

  • Словарные понимания: {k: v for k, v in stuff} означает то же самое, что и dict(stuff), но является более гибким. (Это подтверждает PEP 274. :-)

  • Литералы множеств, например, {1, 2}. Обратите внимание, что {} - это пустой словарь; для пустого множества используйте set(). Также поддерживаются понимания множеств; например, {x for x in stuff} означает то же самое, что и set(stuff), но является более гибким.

  • Новые восьмеричные литералы, например, 0o720 (уже в 2.6). Старые восьмеричные литералы (0720) исчезли.

  • Новые двоичные литералы, например 0b1010 (уже в 2.6), и новая соответствующая встроенная функция bin().

  • Байтовые литералы вводятся с ведущим b или B, и существует новая соответствующая встроенная функция bytes().

Измененный синтаксис

  • PEP 3109 и PEP 3134: новый синтаксис оператора raise: raise [expr [from expr]]. См. ниже.

  • as и with теперь являются зарезервированными словами. (На самом деле, с версии 2.6.)

  • True, False и None являются зарезервированными словами. (В версии 2.6 уже частично введены ограничения на None).

  • Переход от except exc, var к except exc as var. См. PEP 3110.

  • PEP 3115: Новый синтаксис метакласса. Вместо:

    class C:
        __metaclass__ = M
        ...
    

    теперь вы должны использовать:

    class C(metaclass=M):
        ...
    

    Переменная module-global __metaclass__ больше не поддерживается. (Это был костыль для облегчения перехода по умолчанию к классам нового стиля без выведения каждого класса из object).

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

  • Эллипсис* (...) может использоваться в качестве атомарного выражения в любом месте. (Ранее он был разрешен только в срезах.) Кроме того, теперь он должен быть написан как .... (Ранее он также мог быть написан как . . ., по простой случайности грамматики).

Удаленный синтаксис

  • PEP 3113: Распаковка параметров кортежа удалена. Вы больше не можете писать def foo(a, (b, c)): .... Вместо этого используйте def foo(a, b_c): b, c = b_c.

  • Удалены обратные знаки (вместо них используйте repr()).

  • Удалено <> (вместо него используйте !=).

  • Удалено ключевое слово: exec() больше не является ключевым словом; оно осталось в виде функции. (К счастью, синтаксис функции был принят и в 2.x.) Также обратите внимание, что exec() больше не принимает аргумент потока; вместо exec(f) вы можете использовать exec(f.read()).

  • Целочисленные литералы больше не поддерживают трейлинг l или L.

  • Строковые литералы больше не поддерживают ведущие u или U.

  • Синтаксис from module import * разрешен только на уровне модуля, внутри функций он больше не используется.

  • Единственным приемлемым синтаксисом для относительного импорта является from .[module] import name. Все формы import, не начинающиеся с ., интерпретируются как абсолютный импорт. (PEP 328)

  • Классические классы исчезли.

Изменения, уже присутствующие в Python 2.6

Поскольку многие пользователи предположительно переходят сразу с Python 2.5 на Python 3.0, этот раздел напоминает читателю о новых возможностях, которые изначально были разработаны для Python 3.0, но были перенесены в Python 2.6. За более подробным описанием следует обращаться к соответствующим разделам в Что нового в Python 2.6.

Изменения в библиотеке

Из-за нехватки времени в этом документе не исчерпываются очень обширные изменения в стандартной библиотеке. PEP 3108 является справочником по основным изменениям в библиотеке. Вот краткий обзор:

  • Многие старые модули были удалены. Некоторые, такие как gopherlib (больше не используется) и md5 (заменен на hashlib), уже были устаревшими в PEP 4. Другие были удалены в результате прекращения поддержки различных платформ, таких как Irix, BeOS и Mac OS 9 (см. PEP 11). Некоторые модули также были выбраны для удаления в Python 3.0 из-за недостаточного использования или потому, что существует лучшая замена. Исчерпывающий список см. в PEP 3108.

  • Пакет bsddb3 был удален, поскольку его присутствие в стандартной библиотеке ядра оказалось со временем особенно обременительным для разработчиков ядра из-за нестабильности тестирования и графика выпуска Berkeley DB. Тем не менее, пакет жив и здоров, поддерживается извне на сайте https://www.jcea.es/programacion/pybsddb.htm.

  • Некоторые модули были переименованы, потому что их старое имя не подчинялось PEP 8, или по различным другим причинам. Вот список:

    Старое имя

    Новое имя

    _winreg

    winreg

    ConfigParser

    configparser

    copy_reg

    copyreg

    Очередь

    очередь

    SocketServer

    socketserver

    markupbase

    _markupbase

    repr

    reprlib

    test.test_support

    test.support

  • Общим шаблоном в Python 2.x является наличие одной версии модуля, реализованной на чистом Python, с дополнительной ускоренной версией, реализованной как расширение C; например, pickle и cPickle. Это возлагает бремя импорта ускоренной версии и возврата к версии чистого Python на каждого пользователя этих модулей. В Python 3.0 ускоренные версии считаются деталями реализации чистых версий Python. Пользователи всегда должны импортировать стандартную версию, которая пытается импортировать ускоренную версию и возвращается к чистой версии Python. Пара pickle / cPickle получила такой режим. Модуль profile находится в списке для версии 3.1. Модуль StringIO был превращен в класс в модуле io.

  • Некоторые связанные модули были объединены в пакеты, и обычно имена подмодулей были упрощены. В результате получились следующие новые пакеты:

    • dbm (anydbm, dbhash, dbm, dumbdbm, gdbm, whichdb).

    • html (HTMLParser, htmlentitydefs).

    • http (httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib).

    • tkinter (все модули, связанные с Tkinter, кроме turtle). Целевая аудитория turtle не особо интересуется tkinter. Также обратите внимание, что начиная с Python 2.6, функциональность turtle была значительно расширена.

    • urllib (urllib, urllib2, urlparse, robotparse).

    • xmlrpc (xmlrpclib, DocXMLRPCServer, SimpleXMLRPCServer).

Некоторые другие изменения в стандартных библиотечных модулях, не охваченные PEP 3108:

  • Убитый sets. Используйте встроенный класс set().

  • Очистка модуля sys: удалены sys.exitfunc(), sys.exc_clear(), sys.exc_type, sys.exc_value, sys.exc_traceback. (Обратите внимание, что sys.last_type и т.д. остались).

  • Очистка типа array.array: методы read() и write() исчезли; вместо них используйте fromfile() и tofile(). Также исчез тип 'c' для массива - используйте либо 'b' для байтов, либо 'u' для символов Unicode.

  • Очистка модуля operator: удалены sequenceIncludes() и isCallable().

  • Очистка модуля thread: acquire_lock() и release_lock() удалены; вместо них используйте acquire() и release().

  • Очистка модуля random: удален API jumpahead().

  • Модуль new исчез.

  • Функции os.tmpnam(), os.tempnam() и os.tmpfile() были удалены в пользу модуля tempfile.

  • Модуль tokenize был изменен для работы с байтами. Основной точкой входа теперь является tokenize.tokenize(), вместо generate_tokens.

  • string.letters и его друзья (string.lowercase и string.uppercase) исчезли. Вместо них используйте string.ascii_letters и т.д. (Причина удаления в том, что string.letters и друзья имели локально-специфическое поведение, что является плохой идеей для таких привлекательно названных глобальных «констант»).

  • Переименовал модуль __builtin__ в builtins (убрав подчеркивание и добавив „s“). Переменная __builtins__, находящаяся в большинстве глобальных пространств имен, осталась без изменений. Для изменения встроенного модуля следует использовать builtins, а не __builtins__!

PEP 3101: Новый подход к форматированию строк

  • Новая система встроенных операций форматирования строк заменяет оператор форматирования строк %. (Однако оператор % по-прежнему поддерживается; он будет устаревшим в Python 3.1 и удален из языка позднее). Читайте PEP 3101 для полной информации.

Изменения в исключениях

API для создания и перехвата исключений были очищены и добавлены новые мощные функции:

  • PEP 352: Все исключения должны быть производными (прямо или косвенно) от BaseException. Это корень иерархии исключений. Это не новая рекомендация, но требование наследоваться от BaseException является новым. (Python 2.6 все еще позволял поднимать классические классы и не накладывал ограничений на то, что вы можете поймать). Как следствие, строковые исключения наконец-то действительно и окончательно мертвы.

  • Почти все исключения должны происходить от Exception; BaseException следует использовать в качестве базового класса только для исключений, которые должны обрабатываться только на верхнем уровне, например SystemExit или KeyboardInterrupt. Рекомендуемая идиома для обработки всех исключений, кроме этой последней категории, заключается в использовании except Exception.

  • StandardError был удален.

  • Исключения больше не ведут себя как последовательности. Вместо этого используйте атрибут args.

  • PEP 3109: Вызывает исключения. Теперь вы должны использовать raise Exception(args) вместо raise Exception, args. Кроме того, вы больше не можете явно указывать обратную трассировку; вместо этого, если вам нужно это сделать, вы можете назначить непосредственно атрибут __traceback__ (см. ниже).

  • PEP 3110: Ловля исключений. Теперь вы должны использовать except SomeException as variable вместо except SomeException, variable. Более того, переменная явно удаляется при выходе из блока except.

  • PEP 3134: Цепочка исключений. Существует два случая: неявное и явное связывание. Неявная цепочка происходит, когда исключение возникает в блоке обработчика except или finally. Обычно это происходит из-за ошибки в блоке обработчика; мы называем это вторичным исключением. В этом случае исходное исключение (которое обрабатывалось) сохраняется как атрибут __context__ вторичного исключения. Явная цепочка вызывается с помощью следующего синтаксиса:

    raise SecondaryException() from primary_exception
    

    (где primary_exception - любое выражение, которое создает объект исключения, возможно, ранее пойманное исключение). В этом случае первичное исключение хранится в атрибуте __cause__ вторичного исключения. Отслеживание, выводимое при возникновении необработанного исключения, проходит по цепочке атрибутов __cause__ и __context__ и выводит отдельное отслеживание для каждого компонента цепочки, с первичным исключением наверху. (Пользователи Java могут узнать такое поведение).

  • PEP 3134: Объекты исключений теперь хранят свой обратный след как атрибут __traceback__. Это означает, что объект исключения теперь содержит всю информацию, относящуюся к исключению, и теперь меньше причин использовать sys.exc_info() (хотя последний не удален).

  • Улучшено несколько сообщений об исключениях, когда Windows не удается загрузить модуль расширения. Например, error code 193 теперь %1 is not a valid Win32 application. Строки теперь работают с неанглийскими локалями.

Разное Прочие изменения

Операторы и специальные методы

  • != теперь возвращает противоположное ==, если == не возвращает NotImplemented.

  • Концепция «несвязанных методов» была удалена из языка. При ссылке на метод как на атрибут класса, вы теперь получаете обычный объект функции.

  • __getslice__(), __setslice__() и __delslice__() были убиты. Синтаксис a[i:j] теперь переводится как a.__getitem__(slice(i, j)) (или __setitem__() или __delitem__(), когда используется как цель присваивания или удаления, соответственно).

  • PEP 3114: стандартный метод next() был переименован в __next__().

  • Специальные методы __oct__() и __hex__() удалены – oct() и hex() теперь используют __index__() для преобразования аргумента в целое число.

  • Удалена поддержка __members__ и __methods__.

  • Атрибуты функций с именем func_X были переименованы в форму __X__, освобождая эти имена в пространстве имен атрибутов функций для атрибутов, определяемых пользователем. Так, func_closure, func_code, func_defaults, func_dict, func_doc, func_globals, func_name были переименованы в __closure__, __code__, __defaults__, __dict__, __doc__, __globals__, __name__ соответственно.

  • __nonzero__() теперь __bool__().

Встроенные модули

  • PEP 3135: Новый super(). Теперь вы можете вызывать super() без аргументов, и (при условии, что это обычный метод экземпляра, определенный внутри оператора class) нужный класс и экземпляр будут выбраны автоматически. При наличии аргументов поведение super() остается неизменным.

  • PEP 3111: raw_input() была переименована в input(). То есть, новая функция input() читает строку из sys.stdin и возвращает ее с вычеркнутой новой строкой. При преждевременном завершении ввода она выдает сообщение EOFError. Чтобы получить старое поведение input(), используйте eval(input()).

  • Добавлена новая встроенная функция next() для вызова метода __next__() на объекте.

  • Стратегия округления функции round() и тип возврата изменились. Точные половинные случаи теперь округляются до ближайшего четного результата, а не от нуля. (Например, round(2.5) теперь возвращает 2, а не 3). round(x[, n]) теперь делегируется x.__round__([n]) вместо того, чтобы всегда возвращать float. Обычно он возвращает целое число при вызове с одним аргументом и значение того же типа, что и x при вызове с двумя аргументами.

  • Переместил intern() на sys.intern().

  • Удалено: apply(). Вместо apply(f, args) используйте f(*args).

  • Убрано callable(). Вместо callable(f) можно использовать isinstance(f, collections.Callable). Функция operator.isCallable() также исчезла.

  • Удалено coerce(). Эта функция больше не служит цели теперь, когда классические классы исчезли.

  • Удалено execfile(). Вместо execfile(fn) используйте exec(open(fn).read()).

  • Удален тип file. Используйте open(). Теперь существует несколько различных видов потоков, которые open может возвращать в модуле io.

  • Убрано reduce(). Используйте functools.reduce(), если это действительно необходимо; однако в 99 процентах случаев явный цикл for более читабелен.

  • Удалено reload(). Используйте imp.reload().

  • Удалено. dict.has_key() – вместо него используйте оператор in.

Изменения в API Build и C

Из-за нехватки времени здесь приведен очень неполный список изменений в C API.

  • Была прекращена поддержка нескольких платформ, включая, но не ограничиваясь Mac OS 9, BeOS, RISCOS, Irix и Tru64.

  • PEP 3118: Новый API буфера.

  • PEP 3121: Инициализация и финализация модуля расширения.

  • PEP 3123: Приведение PyObject_HEAD в соответствие со стандартом C.

  • Больше нет поддержки C API для ограниченного выполнения.

  • С API PyNumber_Coerce(), PyNumber_CoerceEx(), PyMember_Get() и PyMember_Set() удалены.

  • Новый C API PyImport_ImportModuleNoBlock(), работает как PyImport_ImportModule(), но не блокирует блокировку импорта (вместо этого возвращает ошибку).

  • Переименованы слот и метод C-уровня преобразования булевых значений: nb_nonzero теперь nb_bool.

  • Удалены METH_OLDARGS и WITH_CYCLE_GC из API языка C.

Производительность

Чистым результатом обобщений 3.0 является то, что Python 3.0 работает в бенчмарке pystone примерно на 10% медленнее, чем Python 2.5. Скорее всего, основной причиной этого является удаление специального корпуса для маленьких целых чисел. Есть возможность для улучшения, но это произойдет после выхода 3.0!

Переход на Python 3.0

Для переноса существующего исходного кода Python 2.5 или 2.6 на Python 3.0 лучшей стратегией будет следующая:

  1. (Предварительное условие:) Начните с отличного тестового покрытия.

  2. Перенос на Python 2.6. Это должно быть не сложнее, чем средний перенос с Python 2.x на Python 2.(x+1). Убедитесь, что все ваши тесты прошли.

  3. (Все еще используете 2.6:) Включите переключатель командной строки -3. Это включит предупреждения о функциях, которые будут удалены (или изменены) в версии 3.0. Запустите ваш набор тестов снова и исправляйте код, о котором вы получаете предупреждения, пока не останется ни одного предупреждения, и все ваши тесты по-прежнему будут проходить.

  4. Запустите транслятор исходного кода 2to3 на дереве исходного кода. (Подробнее об этом инструменте см. 2to3 — Автоматизированная трансляция кода Python 2 в 3) Запустите результат трансляции под Python 3.0. Вручную устраните все оставшиеся проблемы, исправляя их до тех пор, пока все тесты не пройдут снова.

Не рекомендуется пытаться писать исходный код, который работает без изменений как под Python 2.6, так и под 3.0; вам придется использовать очень извращенный стиль кодирования, например, избегая операторов print, метаклассов и многого другого. Если вы поддерживаете библиотеку, которая должна поддерживать как Python 2.6, так и Python 3.0, лучшим подходом будет изменение шага 3 выше путем редактирования версии исходного кода 2.6 и повторного запуска транслятора 2to3, а не редактирование версии исходного кода 3.0.

О переносе расширений C на Python 3.0 смотрите Перенос модулей расширения на Python 3.

Вернуться на верх