Документация Python неофициальный перевод

2.5.md

1272 строк · 160.2 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.15/whatsnew/2.5.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Что нового в Python 2.589**Автор:**1011A.M. Kuchling1213В этой статье описываются новые возможности Python 2.5. Финальный релиз Python 2.5 был запланирован на август 2006 года; [**PEP 356**](https://python-all.ru/3.15/whatsnew/2.5.html) описывает запланированный график выпуска. Python 2.5 был выпущен 19 сентября 2006 года.1415Изменения в Python 2.5 представляют собой интересное сочетание улучшений языка и библиотеки. Улучшения библиотеки, думаю, будут более важны для сообщества пользователей Python, поскольку были добавлены несколько широко полезных пакетов. Новые модули включают ElementTree для обработки XML (`xml.etree`), модуль базы данных SQLite (`sqlite`) и модуль [`ctypes`](https://python-all.ru/3.15/library/ctypes.html#module-ctypes) для вызова C-функций.1617Изменения в языке имеют среднюю значимость. Было добавлено несколько приятных новых возможностей, но большинство из них не являются функциями, которыми вы будете пользоваться каждый день. Наконец-то в язык были добавлены условные выражения с использованием нового синтаксиса; см. раздел [PEP 308: Условные выражения](https://python-all.ru/3.15/whatsnew/2.5.html#pep-308). Новый оператор ‘[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)’ упростит написание кода очистки (раздел [PEP 343: Оператор with](https://python-all.ru/3.15/whatsnew/2.5.html#pep-343)). Теперь значения можно передавать в генераторы (раздел [PEP 342: Новые возможности генераторов](https://python-all.ru/3.15/whatsnew/2.5.html#pep-342)). Импорт теперь может быть как абсолютным, так и относительным (раздел [PEP 328: Абсолютный и относительный импорт](https://python-all.ru/3.15/whatsnew/2.5.html#pep-328)). Некоторые граничные случаи обработки исключений обрабатываются лучше (раздел [PEP 341: Унифицированный try/except/finally](https://python-all.ru/3.15/whatsnew/2.5.html#pep-341)). Все эти улучшения стоят того, но они относятся к той или иной конкретной языковой возможности; ни одно из них не является широкими изменениями семантики Python.1819Помимо дополнений в языке и библиотеке, по всему дереву исходного кода были внесены другие улучшения и исправления ошибок. Поиск по журналам изменений SVN показывает, что между Python 2.4 и 2.5 было применено 353 патча и исправлено 458 ошибок. (Обе цифры, вероятно, занижены.)2021Эта статья не претендует на полную спецификацию новых возможностей; вместо этого изменения кратко представлены с помощью полезных примеров. Для получения полной информации всегда обращайтесь к документации Python 2.5 по адресу [https://docs.python.org](https://python-all.ru/3.15/index.html). Если вы хотите понять полную реализацию и обоснование дизайна, обратитесь к PEP для соответствующей новой возможности.2223Комментарии, предложения и сообщения об ошибках по этому документу приветствуются; пожалуйста, отправляйте их автору по электронной почте или открывайте ошибку в трекере ошибок Python.2425## PEP 308: Условные выражения2627Долгое время люди просили способ писать условные выражения, то есть выражения, которые возвращают значение A или значение B в зависимости от того, истинно ли логическое значение или ложно. Условное выражение позволяет написать один оператор присваивания, который имеет тот же эффект, что и следующий:2829```python30if condition:31    x = true_value32else:33    x = false_value34```3536Бесконечные утомительные обсуждения синтаксиса велись как в python-dev, так и в comp.lang.python. Был даже проведен опрос, который показал, что большинство голосующих хотят условные выражения в какой-либо форме, но не было синтаксиса, которому отдавала предпочтение явное большинство. Кандидаты включали C’s `cond ? true_v : false_v`, `if cond then true_v else false_v` и 16 других вариантов.3738Гвидо ван Россум в итоге выбрал удивительный синтаксис:3940```python41x = true_value if condition else false_value42```4344Вычисление по-прежнему ленивое, как и в существующих логических выражениях, поэтому порядок вычисления немного прыгает. Выражение *condition* посередине вычисляется первым, а выражение *true\_value* вычисляется только в том случае, если условие было истинным. Аналогично, выражение *false\_value* вычисляется только тогда, когда условие ложно.4546Этот синтаксис может показаться странным и обратным; почему условие находится в *середине* выражения, а не в начале, как в C’s `c ? x : y`? Решение было проверено путем применения нового синтаксиса к модулям стандартной библиотеки и анализа того, как читается полученный код. Во многих случаях, когда используется условное выражение, одно значение кажется «обычным случаем», а другое – «исключительным случаем», используемым только в более редких ситуациях, когда условие не выполняется. Условный синтаксис делает этот шаблон немного более очевидным:4748```python49contents = ((doc + '\n') if doc else '')50```5152Я читаю вышеприведенный оператор как означающий «здесь *contents* обычно присваивается значение `doc+'\n'`; иногда *doc* пуст, в этом особом случае возвращается пустая строка». Я сомневаюсь, что буду часто использовать условные выражения, когда нет четкого обычного и необычного случая.5354Были некоторые обсуждения, должен ли язык требовать окружать условные выражения скобками. Было принято решение *не* требовать скобки в грамматике языка Python, но, как вопрос стиля, я думаю, вы всегда должны их использовать. Рассмотрим эти два оператора:5556```python57# Первая версия – без скобок58level = 1 if logging else 05960# Вторая версия – со скобками61level = (1 if logging else 0)62```6364В первой версии, я думаю, глаз читателя может сгруппировать оператор в «level = 1», «if logging», «else 0» и подумать, что условие определяет, выполняется ли присваивание *level*. Вторая версия читается лучше, на мой взгляд, потому что она ясно показывает, что присваивание выполняется всегда, а выбор делается между двумя значениями.6566Еще одна причина для включения скобок: несколько странных комбинаций списковых включений и лямбда-функций могут выглядеть как некорректные условные выражения. См. [**PEP 308**](https://python-all.ru/3.15/whatsnew/2.5.html) для некоторых примеров. Если вы ставите скобки вокруг своих условных выражений, вы не столкнетесь с этой ситуацией.6768> **См. также**69>70> **[**PEP 308**](https://python-all.ru/3.15/whatsnew/2.5.html) – Условные выражения**71>72> PEP написан Гвидо ван Россумом и Раймондом Д. Хеттингером; реализован Томасом Воутерсом.7374## PEP 309: Частичное применение функций7576Модуль [`functools`](https://python-all.ru/3.15/library/functools.html#module-functools) предназначен для содержания инструментов функционального программирования.7778Одним из полезных инструментов в этом модуле является функция `partial()`. Для программ, написанных в функциональном стиле, иногда требуется создать варианты существующих функций с заполненными некоторыми параметрами. Рассмотрим функцию Python `f(a, b, c)`; можно создать новую функцию `g(b, c)`, которая эквивалентна `f(1, b, c)`. Это называется «частичным применением функции».7980`partial()` принимает аргументы `(function, arg1, arg2, ... kwarg1=value1, kwarg2=value2)`. Результирующий объект является вызываемым, поэтому вы можете просто вызвать его, чтобы вызвать *функцию* с заполненными аргументами.8182Вот небольшой, но реалистичный пример:8384```python85import functools8687def log (message, subsystem):88    "Write the contents of 'message' to the specified subsystem."89    print '%s: %s' % (subsystem, message)90    ...9192server_log = functools.partial(log, subsystem='server')93server_log('Unable to open socket')94```9596Вот еще один пример из программы, использующей PyGTK. Здесь контекстно-зависимое всплывающее меню создается динамически. Колбэк, предоставленный для опции меню, является частично примененной версией метода `open_item()`, где первый аргумент уже предоставлен.9798```python99...100class Application:101    def open_item(self, path):102       ...103    def init (self):104        open_func = functools.partial(self.open_item, item_path)105        popup_menu.append( ("Open", open_func, 1) )106```107108Еще одна функция в модуле [`functools`](https://python-all.ru/3.15/library/functools.html#module-functools) – это функция `update_wrapper(wrapper, wrapped)`, которая помогает писать корректные декораторы. `update_wrapper()` копирует атрибуты name, module и docstring в функцию-обертку, чтобы трассировки внутри обернутой функции было легче понять. Например, можно написать:109110```python111def my_decorator(f):112    def wrapper(*args, **kwds):113        print 'Calling decorated function'114        return f(*args, **kwds)115    functools.update_wrapper(wrapper, f)116    return wrapper117```118119`wraps()` – это декоратор, который можно использовать внутри собственных декораторов для копирования информации обернутой функции. Альтернативная версия предыдущего примера будет:120121```python122def my_decorator(f):123    @functools.wraps(f)124    def wrapper(*args, **kwds):125        print 'Calling decorated function'126        return f(*args, **kwds)127    return wrapper128```129130> **См. также**131>132> **[**PEP 309**](https://python-all.ru/3.15/whatsnew/2.5.html) – Частичное применение функций**133>134> PEP предложен и написан Питером Харрисом; реализован Хё-Шиком Чангом и Ником Коглан, с адаптациями Раймонда Хеттингера.135136## PEP 314: Метаданные для пакетов программного обеспечения Python v1.1137138В Distutils добавлена простая поддержка зависимостей. Функция `setup()` теперь имеет именованные параметры `requires`, `provides` и `obsoletes`. При сборке дистрибутива исходного кода с помощью команды `sdist` информация о зависимостях будет записана в файл `PKG-INFO`.139140Ещё один новый именованный параметр – `download_url`. Он должен указывать на URL исходного кода пакета. Это означает, что теперь можно найти запись в индексе пакетов, определить зависимости пакета и загрузить необходимые пакеты.141142```python143VERSION = '1.0'144setup(name='PyPackage',145      version=VERSION,146      requires=['numarray', 'zlib (>=1.1.4)'],147      obsoletes=['OldPackage']148      download_url=('http://www.example.com/pypackage/dist/pkg-%s.tar.gz'149                    % VERSION),150     )151```152153Ещё одно новое усовершенствование индекса пакетов Python по адресу [https://pypi.org](https://python-all.ru/3.15/whatsnew/2.5.html) – хранение архивов исходного кода и бинарных архивов для пакета. Новая команда Distutils **upload** будет загружать пакет в репозиторий.154155Прежде чем пакет можно будет загрузить, нужно уметь собрать дистрибутив с помощью команды Distutils **sdist**. Как только это сработает, можно выполнить `python setup.py upload`, чтобы добавить пакет в архив PyPI. При желании можно подписать пакет GPG, указав параметры `--sign` и `--identity`.156157Загрузка пакетов была реализована Мартином фон Лёвисом и Ричардом Джонсом.158159> **См. также**160>161> **[**PEP 314**](https://python-all.ru/3.15/whatsnew/2.5.html) – Метаданные для пакетов программного обеспечения Python v1.1**162>163> PEP предложен и написан А.М. Кухлингом, Ричардом Джонсом и Фредом Дрейком; реализован Ричардом Джонсом и Фредом Дрейком.164165## PEP 328: Абсолютный и относительный импорт166167Более простая часть [**PEP 328**](https://python-all.ru/3.15/whatsnew/2.5.html) была реализована в Python 2.4: теперь можно было использовать круглые скобки для группировки имён, импортируемых из модуля с помощью оператора `from ... import ...`, что упрощало импорт множества разных имён.168169Более сложная часть была реализована в Python 2.5: теперь можно указать, что импорт модуля должен быть абсолютным или относительным в рамках пакета. Планируется сделать абсолютный импорт по умолчанию в будущих версиях Python.170171Предположим, у вас есть каталог пакета следующей структуры:172173```python174pkg/175pkg/__init__.py176pkg/main.py177pkg/string.py178```179180Это определяет пакет с именем `pkg`, содержащий подмодули `pkg.main` и `pkg.string`.181182Рассмотрим код в модуле `main.py`. Что произойдёт, если выполнить инструкцию `import string`? В Python 2.4 и более ранних версиях сначала будет выполнен поиск в каталоге пакета для относительного импорта, найден файл `pkg/string.py`, его содержимое импортировано как модуль `pkg.string`, и этот модуль будет привязан к имени `string` в пространстве имён модуля `pkg.main`.183184Это нормально, если `pkg.string` – то, что нужно. Но что, если нужен стандартный модуль Python [`string`](https://python-all.ru/3.15/library/string.html#module-string)? Нет чистого способа игнорировать `pkg.string` и найти стандартный модуль; обычно приходилось просматривать содержимое `sys.modules`, что не совсем чистое решение. Пакет `py.std` Хольгера Крекеля предлагает более аккуратный способ импорта из стандартной библиотеки `import py; py.std.string.join()`, но этот пакет доступен не на всех установках Python.185186Чтение кода, использующего относительный импорт, также менее понятно, поскольку читатель может запутаться, какой модуль – [`string`](https://python-all.ru/3.15/library/string.html#module-string) или `pkg.string` – подразумевается. Пользователи Python быстро научились не дублировать имена модулей стандартной библиотеки в именах подмодулей своих пакетов, но невозможно защититься от того, что имя вашего подмодуля будет использовано для нового модуля, добавленного в будущей версии Python.187188В Python 2.5 можно переключить поведение [`import`](https://python-all.ru/3.15/reference/simple_stmts.html#import) на абсолютный импорт с помощью директивы `from __future__ import absolute_import`. Это поведение абсолютного импорта станет по умолчанию в будущей версии (вероятно, Python 2.7). Как только абсолютный импорт станет по умолчанию, `import string` всегда будет находить версию из стандартной библиотеки. Рекомендуется начинать использовать абсолютный импорт как можно чаще, поэтому предпочтительнее писать в коде `from pkg import string`.189190Относительный импорт все ещё возможен: для этого нужно добавить точку в начале имени модуля при использовании формы `from ... import`:191192```python193# Импорт имён из pkg.string194from .string import name1, name2195# Импорт pkg.string196from . import string197```198199Это импортирует модуль [`string`](https://python-all.ru/3.15/library/string.html#module-string) относительно текущего пакета, поэтому в `pkg.main` будет импортировано *name1* и *name2* из `pkg.string`. Дополнительные начальные точки выполняют относительный импорт, начиная с родительского по отношению к текущему пакету. Например, код в модуле `A.B.C` может сделать следующее:200201```python202from . import D                 # Импорт A.B.D203from .. import E                # Импорт A.E204from ..F import G               # Импорт A.F.G205```206207Начальные точки нельзя использовать с формой `import modname` инструкции import, только с формой `from ... import`.208209> **См. также**210>211> **[**PEP 328**](https://python-all.ru/3.15/whatsnew/2.5.html) – Импорт: многострочный и абсолютный/относительный**212>213> PEP написан Aahz; реализован Томасом Ваутерсом.214>215> **[https://pylib.readthedocs.io/](https://python-all.ru/3.15/whatsnew/2.5.html)**216>217> Библиотека py Хольгера Крекеля, содержащая пакет `py.std`.218219## PEP 338: Выполнение модулей как сценариев220221Ключ [`-m`](https://python-all.ru/3.15/using/cmdline.html#cmdoption-m), добавленный в Python 2.4 для выполнения модуля как сценария, получил несколько новых возможностей. Теперь он реализован не на C внутри интерпретатора Python, а в новом модуле [`runpy`](https://python-all.ru/3.15/library/runpy.html#module-runpy).222223Модуль [`runpy`](https://python-all.ru/3.15/library/runpy.html#module-runpy) реализует более сложный механизм импорта, так что теперь можно запускать модули в пакете, например `pychecker.checker`. Модуль также поддерживает альтернативные механизмы импорта, такие как модуль [`zipimport`](https://python-all.ru/3.15/library/zipimport.html#module-zipimport). Это означает, что можно добавить путь к .zip-архиву в `sys.path`, а затем использовать ключ [`-m`](https://python-all.ru/3.15/using/cmdline.html#cmdoption-m) для выполнения кода из архива.224225> **См. также**226>227> **[**PEP 338**](https://python-all.ru/3.15/whatsnew/2.5.html) – Выполнение модулей как сценариев**228>229> PEP написан и реализован Ником Когленом.230231## PEP 341: Унифицированный try/except/finally232233До Python 2.5 инструкция [`try`](https://python-all.ru/3.15/reference/compound_stmts.html#try) существовала в двух вариантах. Можно было использовать блок [`finally`](https://python-all.ru/3.15/reference/compound_stmts.html#finally), чтобы гарантировать выполнение кода в любом случае, или один или несколько блоков [`except`](https://python-all.ru/3.15/reference/compound_stmts.html#except) для перехвата определённых исключений. Нельзя было комбинировать блоки `except` и блок `finally`, потому что генерация правильного байт-кода для комбинированного варианта была сложной, и было неясно, какой должна быть семантика такой инструкции.234235Гвидо ван Россум некоторое время работал с Java, в которой поддерживается комбинация блоков [`except`](https://python-all.ru/3.15/reference/compound_stmts.html#except) и блока [`finally`](https://python-all.ru/3.15/reference/compound_stmts.html#finally), и это прояснило, каким должно быть значение инструкции. В Python 2.5 теперь можно писать:236237```python238try:239    block-1 ...240except Exception1:241    handler-1 ...242except Exception2:243    handler-2 ...244else:245    else-block246finally:247    final-block248```249250Сначала выполняется код в *block-1*. Если код возбуждает исключение, проверяются различные блоки [`except`](https://python-all.ru/3.15/reference/compound_stmts.html#except): если исключение относится к классу `Exception1`, выполняется *handler-1*; иначе если к классу `Exception2`, выполняется *handler-2* и так далее. Если исключение не возбуждено, выполняется *else-block*.251252Независимо от того, что произошло ранее, *блок finally* выполняется после завершения блока кода и обработки всех возникших исключений. Даже если в обработчике исключения или в *блоке else* произошла ошибка и возникло новое исключение, код в *блоке finally* всё равно выполняется.253254> **См. также**255>256> **[**PEP 341**](https://python-all.ru/3.15/whatsnew/2.5.html) – Объединение try-except и try-finally**257>258> Автор PEP – Georg Brandl; реализация – Thomas Lee.259260## PEP 342: Новые возможности генераторов261262Python 2.5 добавляет простой способ передачи значений *в* генератор. Как было введено в Python 2.3, генераторы только выдают результат; после того как код генератора был вызван для создания итератора, не было возможности передать какую-либо новую информацию в функцию при возобновлении её выполнения. Иногда возможность передать какую-то информацию была бы полезна. Кустарные решения этой проблемы включали просмотр кодом генератора глобальной переменной и последующее изменение её значения, либо передачу изменяемого объекта, который вызывающие стороны затем модифицируют.263264Чтобы освежить в памяти основы генераторов, вот простой пример:265266```python267def counter (maximum):268    i = 0269    while i < maximum:270        yield i271        i += 1272```273274При вызове `counter(10)` результатом является итератор, который возвращает значения от 0 до 9. При встрече с оператором [`yield`](https://python-all.ru/3.15/reference/simple_stmts.html#yield) итератор возвращает указанное значение и приостанавливает выполнение функции, сохраняя локальные переменные. Выполнение возобновляется при следующем вызове метода [`next()`](https://python-all.ru/3.15/library/functions.html#next) итератора, продолжая после оператора `yield`.275276В Python 2.3 [`yield`](https://python-all.ru/3.15/reference/simple_stmts.html#yield) был оператором; он не возвращал никакого значения. В Python 2.5 `yield` стал выражением, возвращающим значение, которое можно присвоить переменной или использовать в операциях:277278```python279val = (yield i)280```281282Рекомендуется всегда заключать выражение [`yield`](https://python-all.ru/3.15/reference/simple_stmts.html#yield) в скобки, когда вы что-то делаете с возвращаемым значением, как в примере выше. Скобки не всегда обязательны, но проще всегда их добавлять, чем запоминать, когда они нужны.283284([**PEP 342**](https://python-all.ru/3.15/whatsnew/2.5.html) объясняет точные правила: выражение [`yield`](https://python-all.ru/3.15/reference/simple_stmts.html#yield) всегда должно быть в скобках, за исключением случаев, когда оно находится на верхнем уровне в правой части присваивания. Это означает, что можно написать `val = yield i`, но нужно использовать скобки, когда присутствует операция, как в `val = (yield i) + 12`.)285286Значения отправляются в генератор вызовом его метода `send(value)`. Затем код генератора возобновляется, и выражение [`yield`](https://python-all.ru/3.15/reference/simple_stmts.html#yield) возвращает указанное *значение*. Если вызывается обычный метод [`next()`](https://python-all.ru/3.15/library/functions.html#next), то `yield` возвращает [`None`](https://python-all.ru/3.15/library/constants.html#None).287288Вот предыдущий пример, изменённый для возможности изменения значения внутреннего счётчика.289290```python291def counter (maximum):292    i = 0293    while i < maximum:294        val = (yield i)295        # Если передано значение, изменить counter.296        if val is not None:297            i = val298        else:299            i += 1300```301302А вот пример изменения счётчика:303304```python305>>> it = counter(10)306>>> print it.next()3070308>>> print it.next()3091310>>> print it.send(8)3118312>>> print it.next()3139314>>> print it.next()315Traceback (most recent call last):316  File "t.py", line 15, in ?317    print it.next()318StopIteration319```320321[`yield`](https://python-all.ru/3.15/reference/simple_stmts.html#yield) обычно возвращает [`None`](https://python-all.ru/3.15/library/constants.html#None), поэтому всегда следует проверять этот случай. Не используйте его значение в выражениях, если не уверены, что метод `send()` будет единственным методом для возобновления вашей функции-генератора.322323В дополнение к `send()`, у генераторов есть два других новых метода:324325- `throw(type, value=None, traceback=None)` используется для возбуждения исключения внутри генератора; исключение возбуждается выражением [`yield`](https://python-all.ru/3.15/reference/simple_stmts.html#yield) в точке, где выполнение генератора приостановлено.326- `close()` возбуждает новое исключение [`GeneratorExit`](https://python-all.ru/3.15/library/exceptions.html#GeneratorExit) внутри генератора для завершения итерации. При получении этого исключения код генератора должен либо возбудить `GeneratorExit`, либо [`StopIteration`](https://python-all.ru/3.15/library/exceptions.html#StopIteration). Перехватывать исключение `GeneratorExit` и возвращать значение запрещено – это вызовет [`RuntimeError`](https://python-all.ru/3.15/library/exceptions.html#RuntimeError); если функция возбуждает другое исключение, оно передаётся вызывающему коду. `close()` также будет вызван сборщиком мусора Python при сборке мусора генератора.327328  Если нужно выполнить код очистки при возникновении [`GeneratorExit`](https://python-all.ru/3.15/library/exceptions.html#GeneratorExit), рекомендуется использовать блок `try: ... finally:` вместо перехвата `GeneratorExit`.329330Совокупный эффект этих изменений – превращение генераторов из однонаправленных производителей информации одновременно и в производителей, и в потребителей.331332Генераторы также становятся *корутинами* – более обобщённой формой подпрограмм. Подпрограммы имеют одну точку входа и одну точку выхода (начало функции и оператор [`return`](https://python-all.ru/3.15/reference/simple_stmts.html#return)), но корутины можно запускать, завершать и возобновлять во многих разных точках (операторы [`yield`](https://python-all.ru/3.15/reference/simple_stmts.html#yield)). Предстоит выработать шаблоны эффективного использования корутин в Python.333334Добавление метода `close()` имеет один неочевидный побочный эффект. `close()` вызывается, когда генератор уничтожается сборщиком мусора, поэтому код генератора получает последний шанс выполниться перед уничтожением. Это означает, что операторы `try...finally` в генераторах теперь гарантированно сработают; блок [`finally`](https://python-all.ru/3.15/reference/compound_stmts.html#finally) теперь всегда получит шанс выполниться. Синтаксическое ограничение, запрещавшее смешивать операторы [`yield`](https://python-all.ru/3.15/reference/simple_stmts.html#yield) с блоком `try...finally`, было снято. Это кажется мелкой деталью языка, но использование генераторов и `try...finally` на самом деле необходимо для реализации оператора [`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with), описанного в [**PEP 343**](https://python-all.ru/3.15/whatsnew/2.5.html). Этот новый оператор будет рассмотрен в следующем разделе.335336Ещё один, ещё более эзотерический эффект этого изменения: раньше атрибут `gi_frame` генератора всегда был объектом фрейма. Теперь `gi_frame` может быть `None` после исчерпания генератора.337338> **См. также**339>340> **[**PEP 342**](https://python-all.ru/3.15/whatsnew/2.5.html) - Coroutines via Enhanced Generators**341>342> Авторы PEP – Guido van Rossum и Phillip J. Eby; реализация – Phillip J. Eby. Включает примеры более изощрённого использования генераторов в качестве корутин.343>344> Более ранние версии этих возможностей были предложены в [**PEP 288**](https://python-all.ru/3.15/whatsnew/2.5.html) Рэймондом Хеттингером и в [**PEP 325**](https://python-all.ru/3.15/whatsnew/2.5.html) Самуэле Педрони.345>346> **[https://en.wikipedia.org/wiki/Coroutine](https://python-all.ru/3.15/whatsnew/2.5.html)**347>348> Статья в Википедии о корутинах.349>350> **[https://web.archive.org/web/20160321211320/http://www.sidhe.org/~dan/blog/archives/000178.html](https://python-all.ru/3.15/whatsnew/2.5.html)**351>352> Объяснение корутин с точки зрения Perl, написано Дэном Сугальски.353354## PEP 343: Оператор ‘with’355356Оператор ‘[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)’ делает код понятнее, который ранее использовал блоки `try...finally` для гарантии выполнения кода очистки. В этом разделе я расскажу об операторе в его обычном использовании. В следующем разделе я рассмотрю детали реализации и покажу, как писать объекты для использования с этим оператором.357358Оператор ‘[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)’ – это новая управляющая конструкция, основная структура которой:359360```python361with expression [as variable]:362    with-block363```364365Выражение вычисляется, и оно должно вернуть объект, поддерживающий протокол управления контекстом (то есть имеющий методы [`__enter__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__enter__) и [`__exit__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__exit__).366367Метод [`__enter__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__enter__) объекта вызывается перед выполнением *блока with* и поэтому может выполнять код настройки. Он также может возвращать значение, которое связывается с именем *переменная*, если оно указано. (Обратите внимание, что *переменная* *не* присваивается результат *выражения*.)368369После завершения выполнения *блока with* вызывается метод [`__exit__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__exit__) объекта, даже если блок вызвал исключение, и поэтому он может выполнить код очистки.370371Чтобы включить оператор в Python 2.5, необходимо добавить в модуль следующую директиву:372373```python374from __future__ import with_statement375```376377В Python 2.6 оператор будет включён всегда.378379Некоторые стандартные объекты Python теперь поддерживают протокол управления контекстом и могут использоваться с оператором ‘[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)’. Файловые объекты – один из примеров:380381```python382with open('/etc/passwd', 'r') as f:383    for line in f:384        print line385        ... more processing code ...386```387388После выполнения этого оператора файловый объект *f* будет автоматически закрыт, даже если цикл [`for`](https://python-all.ru/3.15/reference/compound_stmts.html#for) вызвал исключение в середине блока.389390> **Примечание**391>392> В этом случае *f* – это тот же объект, созданный [`open()`](https://python-all.ru/3.15/library/functions.html#open), потому что [`__enter__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__enter__) возвращает *self*.393394Блокировки и переменные условия модуля [`threading`](https://python-all.ru/3.15/library/threading.html#module-threading) также поддерживают оператор ‘[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)’:395396```python397lock = threading.Lock()398with lock:399    # Критическая секция кода400    ...401```402403Блокировка захватывается перед выполнением блока и всегда освобождается после завершения блока.404405Новая функция `localcontext()` в модуле [`decimal`](https://python-all.ru/3.15/library/decimal.html#module-decimal) упрощает сохранение и восстановление текущего десятичного контекста, который инкапсулирует желаемую точность и характеристики округления для вычислений:406407```python408from decimal import Decimal, Context, localcontext409410# Отображается с точностью по умолчанию в 28 знаков411v = Decimal('578')412print v.sqrt()413414with localcontext(Context(prec=16)):415    # Весь код в этом блоке использует точность в 16 знаков.416    # Исходный контекст восстанавливается при выходе из блока.417    print v.sqrt()418```419420### Написание контекстных менеджеров421422Под капотом оператор ‘[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)’ довольно сложен. Большинство людей будут использовать ‘`with`’ только с существующими объектами и не нуждаются в знании этих деталей, поэтому вы можете пропустить остальную часть этого раздела, если захотите. Авторам новых объектов потребуется понять детали базовой реализации, и им стоит продолжить чтение.423424Объяснение протокола управления контекстом на высоком уровне:425426- Выражение вычисляется и должно дать объект, называемый «контекстный менеджер». Контекстный менеджер должен иметь методы [`__enter__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__enter__) и [`__exit__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__exit__).427- Вызывается метод [`__enter__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__enter__) контекстного менеджера. Возвращённое значение присваивается *VAR*. Если конструкция `'as VAR'` отсутствует, значение просто игнорируется.428- Код внутри *блока* выполняется.429- Если в *BLOCK* возникает исключение, вызывается метод `__exit__(type, value, traceback)` с деталями исключения – теми же значениями, которые возвращает [`sys.exc_info()`](https://python-all.ru/3.15/library/sys.html#sys.exc_info). Возвращаемое значение метода определяет, будет ли исключение возбуждено повторно: любое ложное значение приводит к повторному возбуждению, а `True` приведёт к его подавлению. Подавлять исключение стоит крайне редко, потому что в этом случае автор кода, содержащего оператор ‘[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)’, никогда не узнает, что что-то пошло не так.430- Если *блок* не вызвал исключения, метод [`__exit__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__exit__) всё равно вызывается, но *type*, *value* и *traceback* равны `None`.431432Рассмотрим пример. Мы не будем приводить подробный код, а лишь в общих чертах опишем методы, необходимые для базы данных, поддерживающей транзакции.433434(Для тех, кто не знаком с терминологией баз данных: набор изменений в базе данных группируется в транзакцию. Транзакции могут быть либо зафиксированы (committed) – это означает, что все изменения записаны в базу данных, либо откачены (rolled back) – что означает, что все изменения отменены, а база данных не изменена. За дополнительной информацией обращайтесь к любому учебнику по базам данных.)435436Предположим, что существует объект, представляющий подключение к базе данных. Наша цель – позволить пользователю написать такой код:437438```python439db_connection = DatabaseConnection()440with db_connection as cursor:441    cursor.execute('insert into ...')442    cursor.execute('delete from ...')443    # ... дополнительные операции ...444```445446Транзакция должна быть зафиксирована, если код в блоке выполняется без ошибок, или откачена, если возникает исключение. Вот базовый интерфейс для `DatabaseConnection`, который мы будем предполагать:447448```python449class DatabaseConnection:450    # Интерфейс базы данных451    def cursor (self):452        "Returns a cursor object and starts a new transaction"453    def commit (self):454        "Commits current transaction"455    def rollback (self):456        "Rolls back current transaction"457```458459Метод [`__enter__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__enter__) довольно прост: ему нужно только начать новую транзакцию. В данном приложении результирующий объект курсора будет полезным результатом, поэтому метод вернёт его. Затем пользователь может добавить `as cursor` к своему оператору '[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)', чтобы привязать курсор к имени переменной.460461```python462class DatabaseConnection:463    ...464    def __enter__ (self):465        # Код для запуска новой транзакции466        cursor = self.cursor()467        return cursor468```469470Метод [`__exit__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__exit__) – самый сложный, потому что именно в нём должна выполняться большая часть работы. Метод должен проверить, произошло ли исключение. Если исключения не было, транзакция фиксируется. Если было – откатывается.471472В приведённом ниже коде выполнение просто дойдёт до конца функции, вернув значение по умолчанию `None`. Значение `None` ложно, поэтому исключение будет автоматически возбуждено повторно. При желании можно сделать это более явно и добавить оператор [`return`](https://python-all.ru/3.15/reference/simple_stmts.html#return) в отмеченном месте.473474```python475class DatabaseConnection:476    ...477    def __exit__ (self, type, value, tb):478        if tb is None:479            # Исключения нет, поэтому фиксация480            self.commit()481        else:482            # Произошло исключение, поэтому откат483            self.rollback()484            # return False485```486487### Модуль contextlib488489Новый модуль [`contextlib`](https://python-all.ru/3.15/library/contextlib.html#module-contextlib) предоставляет несколько функций и декоратор, которые полезны для написания объектов, используемых с оператором ‘[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)’.490491Декоратор называется `contextmanager()` и позволяет написать одну функцию-генератор вместо определения нового класса. Генератор должен генерировать ровно одно значение. Код до [`yield`](https://python-all.ru/3.15/reference/simple_stmts.html#yield) будет выполнен как метод [`__enter__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__enter__), а сгенерированное значение станет возвращаемым значением метода, которое будет связано с переменной в конструкции `as` оператора ‘[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)’, если она присутствует. Код после `yield` будет выполнен в методе [`__exit__()`](https://python-all.ru/3.15/reference/datamodel.html#object.__exit__). Любое исключение, возникшее в блоке, будет возбуждено оператором `yield`.492493Наш пример с базой данных из предыдущего раздела можно написать с использованием этого декоратора так:494495```python496from contextlib import contextmanager497498@contextmanager499def db_transaction (connection):500    cursor = connection.cursor()501    try:502        yield cursor503    except:504        connection.rollback()505        raise506    else:507        connection.commit()508509db = DatabaseConnection()510with db_transaction(db) as cursor:511    ...512```513514Модуль [`contextlib`](https://python-all.ru/3.15/library/contextlib.html#module-contextlib) также содержит функцию `nested(mgr1, mgr2, ...)`, которая объединяет несколько контекстных менеджеров, чтобы не приходилось писать вложенные операторы '[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)'. В этом примере один оператор '`with`' одновременно запускает транзакцию базы данных и захватывает блокировку потока:515516```python517lock = threading.Lock()518with nested (db_transaction(db), lock) as (cursor, locked):519    ...520```521522Наконец, функция `closing(object)` возвращает *object*, чтобы его можно было связать с переменной, и вызывает `object.close` в конце блока.523524```python525import urllib, sys526from contextlib import closing527528with closing(urllib.urlopen('http://www.yahoo.com')) as f:529    for line in f:530        sys.stdout.write(line)531```532533> **См. также**534>535> **[**PEP 343**](https://python-all.ru/3.15/whatsnew/2.5.html) – Оператор «with»**536>537> PEP написан Гвидо ван Россумом и Ником Когланом; реализован Майком Бландом, Гвидо ван Россумом и Нилом Норвицем. В PEP показан код, генерируемый для оператора '[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)', что может быть полезно для понимания того, как работает этот оператор.538>539> Документация для модуля [`contextlib`](https://python-all.ru/3.15/library/contextlib.html#module-contextlib).540541## PEP 352: Исключения как классы нового стиля542543Классы исключений теперь могут быть классами нового стиля, а не только классическими, и встроенный класс [`Exception`](https://python-all.ru/3.15/library/exceptions.html#Exception), а также все стандартные встроенные исключения ([`NameError`](https://python-all.ru/3.15/library/exceptions.html#NameError), [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError) и т.д.) теперь являются классами нового стиля.544545Иерархия наследования для исключений была немного перестроена. В версии 2.5 отношения наследования таковы:546547```python548BaseException       # Новое в Python 2.5549|- KeyboardInterrupt550|- SystemExit551|- Exception552   |- (all other current built-in exceptions)553```554555Эта перестройка была сделана, потому что разработчики часто хотят перехватывать все исключения, указывающие на ошибки программы. Однако [`KeyboardInterrupt`](https://python-all.ru/3.15/library/exceptions.html#KeyboardInterrupt) и [`SystemExit`](https://python-all.ru/3.15/library/exceptions.html#SystemExit) не являются ошибками и обычно представляют собой явное действие, например, нажатие пользователем `Control`-`C` или вызов кода [`sys.exit()`](https://python-all.ru/3.15/library/sys.html#sys.exit). Голый `except:` перехватит все исключения, поэтому обычно нужно перечислить `KeyboardInterrupt` и `SystemExit`, чтобы пробросить их заново. Обычный шаблон:556557```python558try:559    ...560except (KeyboardInterrupt, SystemExit):561    raise562except:563    # Записать ошибку...564    # Продолжить выполнение программы...565```566567В Python 2.5 теперь можно написать `except Exception` для достижения того же результата: перехватываются все исключения, которые обычно указывают на ошибки, но [`KeyboardInterrupt`](https://python-all.ru/3.15/library/exceptions.html#KeyboardInterrupt) и [`SystemExit`](https://python-all.ru/3.15/library/exceptions.html#SystemExit) остаются нетронутыми. Как и в предыдущих версиях, голый `except:` по-прежнему перехватывает все исключения.568569Цель для Python 3.0 – требовать, чтобы любой класс, возбуждаемый как исключение, наследовал от [`BaseException`](https://python-all.ru/3.15/library/exceptions.html#BaseException) или от какого-либо потомка `BaseException`, и будущие выпуски в серии Python 2.x могут начать применять это ограничение. Поэтому рекомендую уже сейчас сделать так, чтобы все классы исключений наследовали от [`Exception`](https://python-all.ru/3.15/library/exceptions.html#Exception). Высказывались предложения удалить форму голого `except:` в Python 3.0, но Гвидо ван Россум ещё не решил, делать это или нет.570571Возбуждение строк в качестве исключений, как в выражении `raise "Error occurred"`, объявлено устаревшим в Python 2.5 и будет вызывать предупреждение. Цель – иметь возможность удалить возможность строковых исключений через несколько выпусков.572573> **См. также**574>575> **[**PEP 352**](https://python-all.ru/3.15/whatsnew/2.5.html) – Требуемый суперкласс для исключений**576>577> Авторы PEP: Бретт Кэннон и Гвидо ван Россум; реализация – Бретт Кэннон.578579## PEP 353: Использование ssize\_t в качестве типа индекса580581Масштабное изменение в C API Python: использование нового определения типа [`Py_ssize_t`](https://python-all.ru/3.15/c-api/intro.html#c.Py_ssize_t) вместо int позволит интерпретатору обрабатывать больше данных на 64-битных платформах. Это изменение не влияет на производительность Python на 32-битных платформах.582583Различные части интерпретатора Python использовали тип int из C для хранения размеров или количества; например, количество элементов в списке или кортеже хранилось в int. Компиляторы C для большинства 64-битных платформ по-прежнему определяют int как 32-битный тип, поэтому списки могли содержать не более `2**31 - 1` = 2147483647 элементов. (На самом деле существует несколько различных моделей программирования, которые могут использовать 64-битные компиляторы C – см. обсуждение на [https://unix.org/version2/whatsnew/lp64\_wp.html](https://python-all.ru/3.15/whatsnew/2.5.html) – но наиболее распространённая модель оставляет int 32-битным.)584585Ограничение в 2147483647 элементов не имеет особого значения на 32-битной платформе, поскольку память закончится раньше, чем будет достигнут лимит длины. Каждый элемент списка требует места для указателя (4 байта) плюс место для [`PyObject`](https://python-all.ru/3.15/c-api/structures.html#c.PyObject), представляющего элемент. 2147483647\*4 – это уже больше байт, чем может содержать 32-битное адресное пространство.586587Однако на 64-битной платформе можно адресовать такой объём памяти. Указатели для списка такого размера потребуют всего 16 ГиБ пространства, поэтому вполне разумно, что программисты на Python могут создавать такие большие списки. Следовательно, интерпретатор Python пришлось изменить, чтобы использовать какой-то другой тип вместо int, и на 64-битных платформах это будет 64-битный тип. Это изменение вызовет несовместимости на 64-битных машинах, поэтому было решено, что переход стоит сделать сейчас, пока количество 64-битных пользователей ещё относительно невелико. (Через 5 или 10 лет мы, возможно, *все* будем на 64-битных машинах, и переход будет более болезненным.)588589Это изменение сильнее всего затрагивает авторов C-расширений. Строки Python и контейнерные типы, такие как списки и кортежи, теперь используют [`Py_ssize_t`](https://python-all.ru/3.15/c-api/intro.html#c.Py_ssize_t) для хранения своего размера. Такие функции, как [`PyList_Size()`](https://python-all.ru/3.15/c-api/list.html#c.PyList_Size), теперь возвращают `Py_ssize_t`. Поэтому коду в модулях расширений может потребоваться изменить некоторые переменные на `Py_ssize_t`.590591Функции [`PyArg_ParseTuple()`](https://python-all.ru/3.15/c-api/arg.html#c.PyArg_ParseTuple) и [`Py_BuildValue()`](https://python-all.ru/3.15/c-api/arg.html#c.Py_BuildValue) получили новый код преобразования `n` для [`Py_ssize_t`](https://python-all.ru/3.15/c-api/intro.html#c.Py_ssize_t). Функции `PyArg_ParseTuple()`'s `s#` и `t#` по умолчанию по-прежнему выводят int, но можно определить макрос `PY_SSIZE_T_CLEAN` до включения `Python.h`, чтобы они возвращали `Py_ssize_t`.592593[**PEP 353**](https://python-all.ru/3.15/whatsnew/2.5.html) содержит раздел с рекомендациями по преобразованию, который авторы расширений должны прочитать, чтобы узнать о поддержке 64-битных платформ.594595> **См. также**596>597> **[**PEP 353**](https://python-all.ru/3.15/whatsnew/2.5.html) – Использование ssize\_t в качестве типа индекса**598>599> Автор и разработчик PEP – Мартин фон Лёвис.600601## PEP 357: Метод ‘\_\_index\_\_’602603У разработчиков NumPy была проблема, которую можно было решить только добавлением нового специального метода `__index__()`. При использовании нотации срезов, как в `[start:stop:step]`, значения индексов *start*, *stop* и *step* должны быть либо целыми числами (int), либо длинными целыми (long int). NumPy определяет множество специализированных целочисленных типов, соответствующих беззнаковым и знаковым целым размером 8, 16, 32 и 64 бита, но не было способа указать, что эти типы можно использовать в качестве индексов среза.604605Срезы не могут просто использовать существующий метод `__int__()`, потому что этот метод также используется для приведения к целым числам. Если бы срезы использовали `__int__()`, числа с плавающей запятой также стали бы допустимыми индексами срезов, а это явно нежелательное поведение.606607Вместо этого был добавлен новый специальный метод `__index__()`. Он не принимает аргументов и возвращает целое число, дающее индекс среза для использования. Например:608609```python610class C:611    def __index__ (self):612        return self.value613```614615Возвращаемое значение должно быть либо целым числом Python (int), либо длинным целым (long). Интерпретатор проверяет корректность возвращаемого типа и возбуждает [`TypeError`](https://python-all.ru/3.15/library/exceptions.html#TypeError), если это требование не выполнено.616617Соответствующий слот [`nb_index`](https://python-all.ru/3.15/c-api/typeobj.html#c.PyNumberMethods.nb_index) был добавлен в структуру [`PyNumberMethods`](https://python-all.ru/3.15/c-api/typeobj.html#c.PyNumberMethods) на уровне C, чтобы позволить C-расширениям реализовать этот протокол. В коде расширений можно использовать `PyNumber_Index(obj)` для вызова функции `__index__()` и получения её результата.618619> **См. также**620>621> **[**PEP 357**](https://python-all.ru/3.15/whatsnew/2.5.html) – Разрешение использования любого объекта для срезов**622>623> Автор и разработчик PEP – Трэвис Олифант.624625## Прочие изменения языка626627Ниже перечислены все изменения, которые Python 2.5 вносит в ядро языка Python.628629- Тип [`dict`](https://python-all.ru/3.15/library/stdtypes.html#dict) имеет новый перехватчик, позволяющий подклассам предоставлять значение по умолчанию, когда ключ отсутствует в словаре. Когда ключ не найден, вызывается метод `__missing__(key)` словаря. Этот перехватчик используется для реализации нового класса `defaultdict` в модуле [`collections`](https://python-all.ru/3.15/library/collections.html#module-collections). В следующем примере определяется словарь, который возвращает ноль для любого отсутствующего ключа:630631  ```python632  class zerodict (dict):633      def __missing__ (self, key):634          return 0635636  d = zerodict({1:1, 2:2})637  print d[1], d[2]   # Выводит 1, 2638  print d[3], d[4]   # Выводит 0, 0639  ```640- Как 8-битные, так и Unicode-строки получили новые методы `partition(sep)` и `rpartition(sep)`, упрощающие часто встречающийся сценарий использования.641642  Метод `find(S)` часто используется для получения индекса, который затем применяется для выделения подстроки и получения частей до и после разделителя. `partition(sep)` объединяет этот шаблон в один вызов метода, который возвращает кортеж из 3 элементов, содержащий подстроку до разделителя, сам разделитель и подстроку после разделителя. Если разделитель не найден, первый элемент кортежа – вся строка, а два других элемента пусты. `rpartition(sep)` также возвращает кортеж из 3 элементов, но начинает поиск с конца строки; `r` означает «обратный» (reverse).643644  Несколько примеров:645646  ```python647  >>> ('http://www.python.org').partition('://')648  ('http', '://', 'www.python.org')649  >>> ('file:/usr/share/doc/index.html').partition('://')650  ('file:/usr/share/doc/index.html', '', '')651  >>> (u'Subject: a quick question').partition(':')652  (u'Subject', u':', u' a quick question')653  >>> 'www.python.org'.rpartition('.')654  ('www.python', '.', 'org')655  >>> 'www.python.org'.rpartition(':')656  ('', '', 'www.python.org')657  ```658659  (Реализовано Фредриком Лундом по предложению Рэймонда Хеттингера.)660- Методы `startswith()` и `endswith()` строковых типов теперь принимают кортежи строк для проверки.661662  ```python663  def is_image_file (filename):664      return filename.endswith(('.gif', '.jpg', '.tiff'))665  ```666667  (Реализовано Георгом Брандлем по предложению Тома Линна.)668- Встроенные функции [`min()`](https://python-all.ru/3.15/library/functions.html#min) и [`max()`](https://python-all.ru/3.15/library/functions.html#max) получили ключевой параметр `key`, аналогичный аргументу `key` для `sort()`. Этот параметр задает функцию, которая принимает один аргумент и вызывается для каждого значения в списке; `min()`/`max()` вернет элемент с наименьшим/наибольшим возвращаемым значением этой функции. Например, чтобы найти самую длинную строку в списке, можно сделать:669670  ```python671  L = ['medium', 'longest', 'short']672  # Выводит 'longest'673  print max(L, key=len)674  # Выводит 'short', потому что лексикографически 'short' имеет наибольшее значение675  print max(L)676  ```677678  (Авторы: Стивен Бетард и Рэймонд Хеттингер.)679- Две новые встроенные функции, [`any()`](https://python-all.ru/3.15/library/functions.html#any) и [`all()`](https://python-all.ru/3.15/library/functions.html#all), проверяют, содержит ли итератор хотя бы одно истинное или ложное значение. `any()` возвращает [`True`](https://python-all.ru/3.15/library/constants.html#True), если хотя бы одно значение, возвращаемое итератором, истинно; в противном случае возвращает [`False`](https://python-all.ru/3.15/library/constants.html#False). `all()` возвращает `True` только в том случае, если все значения, возвращаемые итератором, оцениваются как истинные. (Предложено Гвидо ван Россумом, реализовано Рэймондом Хеттингером.)680- Результат метода `__hash__()` класса теперь может быть как длинным целым, так и обычным целым. Если возвращается длинное целое, берется хеш этого значения. В более ранних версиях хеш-значение должно было быть обычным целым, но в 2.5 встроенная функция [`id()`](https://python-all.ru/3.15/library/functions.html#id) была изменена так, чтобы всегда возвращать неотрицательные числа, и пользователи часто используют `id(self)` в методах `__hash__()` (хотя это не рекомендуется).681- Теперь ASCII является кодировкой по умолчанию для модулей. Если модуль содержит строковые литералы с 8-битными символами, но не имеет декларации кодировки, это теперь синтаксическая ошибка. В Python 2.4 это вызывало предупреждение, а не синтаксическую ошибку. См. [**PEP 263**](https://python-all.ru/3.15/whatsnew/2.5.html) для получения информации о том, как объявить кодировку модуля; например, можно добавить строку в верхней части исходного файла:682683  ```python684  # -*- coding: latin1 -*-685  ```686- Новое предупреждение [`UnicodeWarning`](https://python-all.ru/3.15/library/exceptions.html#UnicodeWarning) возникает при попытке сравнить строку Unicode и 8-битную строку, которую невозможно преобразовать в Unicode с использованием кодировки ASCII по умолчанию. Результат сравнения – ложь:687688  ```python689  >>> chr(128) == unichr(128)   # Не удаётся преобразовать chr(128) в Unicode690  __main__:1: UnicodeWarning: Unicode equal comparison failed691    to convert both arguments to Unicode - interpreting them692    as being unequal693  False694  >>> chr(127) == unichr(127)   # chr(127) можно преобразовать695  True696  ```697698  Раньше это вызывало исключение [`UnicodeDecodeError`](https://python-all.ru/3.15/library/exceptions.html#UnicodeDecodeError), но в версии 2.5 это могло приводить к запутанным проблемам при обращении к словарю. Если выполнялся поиск `unichr(128)` и `chr(128)` использовался в качестве ключа, возникало исключение `UnicodeDecodeError`. Другие изменения в 2.5 привели к тому, что это исключение теперь возбуждается, а не подавляется кодом в `dictobject.c`, реализующим словари.699700  Возбуждение исключения для такого сравнения строго корректно, но изменение могло нарушить существующий код, поэтому вместо этого было введено [`UnicodeWarning`](https://python-all.ru/3.15/library/exceptions.html#UnicodeWarning).701702  (Реализовано Марк-Андре Лембургом.)703- Одна из ошибок, которую иногда допускают Python-программисты, – забыть включить модуль `__init__.py` в каталог пакета. Отладка этой ошибки может сбивать с толку и обычно требует запуска Python с ключом [`-v`](https://python-all.ru/3.15/using/cmdline.html#cmdoption-v) для регистрации всех путей поиска. В Python 2.5 новое предупреждение [`ImportWarning`](https://python-all.ru/3.15/library/exceptions.html#ImportWarning) возникает, когда импорт мог бы выбрать каталог в качестве пакета, но `__init__.py` не найден. По умолчанию это предупреждение игнорируется; для отображения сообщения укажите параметр [`-Wd`](https://python-all.ru/3.15/using/cmdline.html#cmdoption-W) при запуске исполняемого файла Python. (Реализовано Томасом Ваутерсом.)704- Список базовых классов в определении класса теперь может быть пустым. Например, теперь это допустимо:705706  ```python707  class C():708      pass709  ```710711  (Реализовано Бреттом Кэнноном.)712713### Изменения в интерактивном интерпретаторе714715В интерактивном интерпретаторе `quit` и `exit` долгое время были строками, чтобы новые пользователи получали относительно полезное сообщение при попытке выйти:716717```python718>>> quit719'Use Ctrl-D (i.e. EOF) to exit.'720```721722В Python 2.5 `quit` и `exit` теперь являются объектами, которые по-прежнему дают строковое представление самих себя, но также являются вызываемыми. Новички, которые попробуют `quit()` или `exit()`, теперь выйдут из интерпретатора, как и ожидается. (Реализовано Георгом Брандлем.)723724Исполняемый файл Python теперь принимает стандартные длинные опции [`--help`](https://python-all.ru/3.15/using/cmdline.html#cmdoption-help) и [`--version`](https://python-all.ru/3.15/using/cmdline.html#cmdoption-version); в Windows он также принимает опцию [`/?`](https://python-all.ru/3.15/using/cmdline.html#cmdoption-0) для вывода справочного сообщения. (Реализовано Георгом Брандлем.)725726### Оптимизации727728Некоторые из оптимизаций были разработаны на спринте NeedForSpeed, проходившем в Рейкьявике, Исландия, с 21 по 28 мая 2006 года. Спринт был посвящен повышению производительности реализации CPython и финансировался компанией EWT LLC при локальной поддержке CCP Games. Оптимизации, добавленные на этом спринте, отмечены особым образом в следующем списке.729730- Когда встроенные типы [`set`](https://python-all.ru/3.15/library/stdtypes.html#set) и [`frozenset`](https://python-all.ru/3.15/library/stdtypes.html#frozenset) были представлены в Python 2.4, они были реализованы поверх словарного типа Python. В версии 2.5 внутренняя структура данных была настроена специально для реализации множеств, и в результате множества потребляют на треть меньше памяти и работают несколько быстрее. (Реализовано Рэймондом Хеттингером.)731- Скорость некоторых операций с Unicode, таких как поиск подстрок, разделение строк, а также кодирование и декодирование с помощью символьных карт, была повышена. (Улучшения поиска подстрок и разделения строк были добавлены Фредриком Лундом и Эндрю Далком на спринте NeedForSpeed. Символьные карты улучшены Вальтером Дёрвальдом и Мартином фон Лёвисом.)732- Функция `long(str, base)` теперь работает быстрее с длинными строками цифр, так как вычисляется меньше промежуточных результатов. Пик – для строк из примерно 800–1000 цифр, где функция работает в 6 раз быстрее. (Автор: Алан Макинтайр, добавлено на спринте NeedForSpeed.)733- Теперь запрещено смешивать итерацию по файлу с помощью `for line in file` и вызов методов `read()`/[`readline()`](https://python-all.ru/3.15/library/readline.html#module-readline)/`readlines()` объекта файла. Итерация использует внутренний буфер, а методы `read*()` этот буфер не используют. Вместо этого они возвращают данные, следующие за буфером, что приводит к нарушению порядка данных. Смешивание итерации и этих методов теперь вызывает [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError) из метода `read*()`. (Реализовано Томасом Ваутерсом.)734- Модуль [`struct`](https://python-all.ru/3.15/library/struct.html#module-struct) теперь компилирует строки формата структур во внутреннее представление и кэширует его, что дает ускорение на 20%. (Автор: Боб Ипполито на спринте NeedForSpeed.)735- Модуль [`re`](https://python-all.ru/3.15/library/re.html#module-re) получил ускорение на 1–2% за счет перехода на функции распределения памяти Python вместо системных `malloc()` и `free()`. (Автор: Джек Дидерих на спринте NeedForSpeed.)736- Оптимизатор "peephole" генератора кода теперь выполняет простое сворачивание констант в выражениях. Если написать что-то вроде `a = 2+3`, генератор кода выполнит арифметическую операцию и создаст код, соответствующий `a = 5`. (Предложено и реализовано Рэймондом Хеттингером.)737- Вызовы функций теперь выполняются быстрее, поскольку объекты кода теперь хранят последний завершенный фрейм ("zombie frame") во внутреннем поле объекта кода и повторно используют его при следующем вызове. (Оригинальный патч Майкла Хадсона, модифицирован Армином Риго и Ричардом Джонсом; добавлен на спринте NeedForSpeed.) Объекты фреймов также стали немного меньше, что может улучшить локальность кэша и немного уменьшить потребление памяти. (Автор: Нил Норвиц.)738- Встроенные исключения Python теперь являются классами нового стиля, что значительно ускоряет их создание. Обработка исключений в Python 2.5 выполняется примерно на 30% быстрее, чем в 2.4. (Авторы: Ричард Джонс, Георг Брандль и Шон Райфшнайдер на спринте NeedForSpeed.)739- Импорт теперь кэширует проверенные пути, записывая, существуют они или нет, чтобы интерпретатор совершал меньше вызовов `open()` и `stat()` при запуске. (Авторы: Мартин фон Лёвис и Георг Брандль.)740741## Новые, улучшенные и удаленные модули742743Стандартная библиотека получила множество улучшений и исправлений ошибок в Python 2.5. Вот частичный список наиболее заметных изменений, отсортированных по модулям в алфавитном порядке. Обратитесь к файлу `Misc/NEWS` в дереве исходного кода для получения более полного списка изменений или просмотрите журналы SVN для получения всех подробностей.744745- Модуль `audioop` теперь поддерживает кодировку a-LAW, а код для кодировки u-LAW был улучшен. (Автор: Lars Immisch.)746- Модуль [`codecs`](https://python-all.ru/3.15/library/codecs.html#module-codecs) получил поддержку инкрементальных кодеков. Функция `codec.lookup()` теперь возвращает экземпляр `CodecInfo` вместо кортежа. Экземпляры `CodecInfo` ведут себя как 4-кортеж для сохранения обратной совместимости, но также имеют атрибуты `encode`, `decode`, `incrementalencoder`, `incrementaldecoder`, `streamwriter` и `streamreader`. Инкрементальные кодеки могут получать входные данные и создавать выходные по частям; результат будет таким же, как если бы все входные данные были переданы неинкрементальному кодеку. Подробнее см. документацию модуля `codecs`. (Разработано и реализовано Walter Dörwald.)747- Модуль [`collections`](https://python-all.ru/3.15/library/collections.html#module-collections) получил новый тип `defaultdict`, который наследует стандартному типу [`dict`](https://python-all.ru/3.15/library/stdtypes.html#dict). Новый тип в основном ведёт себя как словарь, но создаёт значение по умолчанию, когда ключ отсутствует, автоматически добавляя его в словарь для запрошенного ключа.748749  Первый аргумент конструктора `defaultdict` – это фабричная функция, которая вызывается всякий раз, когда запрашивается отсутствующий ключ. Эта функция не принимает аргументов, поэтому можно использовать встроенные конструкторы типов, такие как [`list()`](https://python-all.ru/3.15/library/stdtypes.html#list) или [`int()`](https://python-all.ru/3.15/library/functions.html#int). Например, можно создать индекс слов по их первой букве следующим образом:750751  ```python752  words = """Nel mezzo del cammin di nostra vita753  mi ritrovai per una selva oscura754  che la diritta via era smarrita""".lower().split()755756  index = defaultdict(list)757758  for w in words:759      init_letter = w[0]760      index[init_letter].append(w)761  ```762763  Вывод `index` даёт следующий результат:764765  ```python766  defaultdict(<type 'list'>, {'c': ['cammin', 'che'], 'e': ['era'],767          'd': ['del', 'di', 'diritta'], 'm': ['mezzo', 'mi'],768          'l': ['la'], 'o': ['oscura'], 'n': ['nel', 'nostra'],769          'p': ['per'], 's': ['selva', 'smarrita'],770          'r': ['ritrovai'], 'u': ['una'], 'v': ['vita', 'via']}771  ```772773  (Автор: Guido van Rossum.)774- Тип двусторонней очереди `deque` из модуля [`collections`](https://python-all.ru/3.15/library/collections.html#module-collections) теперь имеет метод `remove(value)`, который удаляет первое вхождение *значения* в очереди, вызывая [`ValueError`](https://python-all.ru/3.15/library/exceptions.html#ValueError), если значение не найдено. (Автор: Raymond Hettinger.)775- Новый модуль: модуль [`contextlib`](https://python-all.ru/3.15/library/contextlib.html#module-contextlib) содержит вспомогательные функции для использования с новым оператором «[`with`](https://python-all.ru/3.15/reference/compound_stmts.html#with)». Дополнительную информацию об этом модуле см. в разделе [Модуль contextlib](https://python-all.ru/3.15/whatsnew/2.5.html#contextlibmod).776- Новый модуль: модуль `cProfile` – это реализация существующего модуля `profile` на языке C с гораздо меньшими накладными расходами. Интерфейс модуля такой же, как у `profile`: вы запускаете `cProfile.run('main()')` для профилирования функции, можете сохранять данные профилирования в файл и т. д. Пока неизвестно, будет ли профилировщик Hotshot, который также написан на C, но не соответствует интерфейсу модуля `profile`, поддерживаться в будущих версиях Python. (Автор: Armin Rigo.)777778  Кроме того, модуль [`pstats`](https://python-all.ru/3.15/library/pstats.html#module-pstats) для анализа данных, полученных профилировщиком, теперь поддерживает направление вывода в любой файловый объект путём передачи аргумента *поток данных* конструктору `Stats`. (Автор: Skip Montanaro.)779- Модуль [`csv`](https://python-all.ru/3.15/library/csv.html#module-csv), который анализирует файлы в формате CSV (значения, разделённые запятыми), получил несколько улучшений и ряд исправлений ошибок. Теперь можно задать максимальный размер поля в байтах, вызвав функцию `csv.field_size_limit(new_limit)`; если опустить аргумент *new\_limit*, будет возвращён текущий лимит. Класс `reader` теперь имеет атрибут `line_num`, который подсчитывает количество физических строк, прочитанных из источника; записи могут занимать несколько физических строк, поэтому `line_num` не совпадает с количеством прочитанных записей.780781  Парсер CSV теперь более строг в отношении многострочных полей в кавычках. Ранее, если строка заканчивалась внутри поля в кавычках без завершающего символа новой строки, в возвращаемое поле вставлялся символ новой строки. Такое поведение вызывало проблемы при чтении файлов, содержащих символы возврата каретки внутри полей, поэтому код был изменён для возврата поля без вставки символов новой строки. Как следствие, если символы новой строки внутри полей важны, входные данные следует разбивать на строки таким образом, чтобы эти символы сохранялись.782783  (Авторы: Skip Montanaro и Andrew McNamara.)784- Класс [`datetime`](https://python-all.ru/3.15/library/datetime.html#datetime.datetime) в модуле [`datetime`](https://python-all.ru/3.15/library/datetime.html#module-datetime) теперь имеет метод `strptime(string, format)` для разбора строк даты, добавленный Josh Spoerri. Он использует те же символы форматирования, что и [`time.strptime()`](https://python-all.ru/3.15/library/time.html#time.strptime) и [`time.strftime()`](https://python-all.ru/3.15/library/time.html#time.strftime):785786  ```python787  import datetime as dt788789  ts = dt.datetime.strptime('10:13:15 2006-03-07',790                            '%H:%M:%S %Y-%m-%d')791  ```792- Метод `SequenceMatcher.get_matching_blocks()` в модуле [`difflib`](https://python-all.ru/3.15/library/difflib.html#module-difflib) теперь гарантирует возврат минимального списка блоков, описывающих совпадающие подпоследовательности. Ранее алгоритм иногда разбивал блок совпадающих элементов на две записи списка. (Улучшение от Tim Peters.)793- Модуль [`doctest`](https://python-all.ru/3.15/library/doctest.html#module-doctest) получил опцию `SKIP`, которая полностью предотвращает выполнение примера. Это предназначено для фрагментов кода, которые являются примерами использования для читателя и не являются тестовыми примерами.794795  Параметр *encoding* был добавлен в функцию `testfile()` и класс `DocFileSuite` для указания кодировки файла. Это упрощает использование не-ASCII символов в тестах, содержащихся в строке документации. (Автор: Bjorn Tillenius.)796- Пакет [`email`](https://python-all.ru/3.15/library/email.html#module-email) обновлён до версии 4.0. (Автор: Barry Warsaw.)797- Модуль [`fileinput`](https://python-all.ru/3.15/library/fileinput.html#module-fileinput) стал более гибким. Теперь поддерживаются имена файлов в Юникоде, а в функцию [`input()`](https://python-all.ru/3.15/library/functions.html#input) добавлен параметр *mode*, по умолчанию равный `"r"`, позволяющий открывать файлы в двоичном режиме или в режиме [универсальных символов новой строки](https://python-all.ru/3.15/glossary.html#term-universal-newlines). Ещё один новый параметр, *openhook*, позволяет использовать функцию, отличную от [`open()`](https://python-all.ru/3.15/library/functions.html#open), для открытия входных файлов. При итерации по набору файлов новый метод [`fileno()`](https://python-all.ru/3.15/library/fileinput.html#fileinput.fileno) объекта `FileInput` возвращает файловый дескриптор для текущего открытого файла. (Автор: Georg Brandl.)798- В модуле [`gc`](https://python-all.ru/3.15/library/gc.html#module-gc) новая функция `get_count()` возвращает 3-кортеж, содержащий текущие счётчики коллекций для трёх поколений GC. Это учётная информация для сборщика мусора; когда эти счётчики достигают заданного порога, выполняется сборка мусора. Существующая функция [`gc.collect()`](https://python-all.ru/3.15/library/gc.html#gc.collect) теперь принимает необязательный аргумент *generation* со значениями 0, 1 или 2 для указания того, какое поколение следует собирать. (Автор: Barry Warsaw.)799- Функции `nsmallest()` и `nlargest()` в модуле [`heapq`](https://python-all.ru/3.15/library/heapq.html#module-heapq) теперь поддерживают именованный параметр `key`, аналогичный тому, который предоставляется функциями [`min()`](https://python-all.ru/3.15/library/functions.html#min)/[`max()`](https://python-all.ru/3.15/library/functions.html#max) и методами `sort()`. Например:800801  ```python802  >>> import heapq803  >>> L = ["short", 'medium', 'longest', 'longer still']804  >>> heapq.nsmallest(2, L)  # Возвращает два наименьших элемента в лексикографическом порядке805  ['longer still', 'longest']806  >>> heapq.nsmallest(2, L, key=len)   # Возвращает два самых коротких элемента807  ['short', 'medium']808  ```809810  (Автор: Raymond Hettinger.)811- Функция [`itertools.islice()`](https://python-all.ru/3.15/library/itertools.html#itertools.islice) теперь принимает `None` для аргументов start и step. Это делает её более совместимой с атрибутами объектов среза, так что теперь можно написать следующее:812813  ```python814  s = slice(5)     # Создать объект среза815  itertools.islice(iterable, s.start, s.stop, s.step)816  ```817818  (Автор: Raymond Hettinger.)819- Функция [`format()`](https://python-all.ru/3.15/library/functions.html#format) в модуле [`locale`](https://python-all.ru/3.15/library/locale.html#module-locale) была изменена, и добавлены две новые функции: `format_string()` и `currency()`.820821  Параметр *val* функции [`format()`](https://python-all.ru/3.15/library/functions.html#format) ранее мог быть строкой при условии, что в ней присутствовал не более одного спецификатора %char; теперь параметр должен содержать ровно один спецификатор %char без окружающего текста. Также был добавлен необязательный параметр *monetary*, который, если равен `True`, будет использовать правила локали для форматирования денежных значений при расстановке разделителей между группами из трёх цифр.822823  Для форматирования строк с несколькими спецификаторами %char используйте новую функцию `format_string()`, которая работает как [`format()`](https://python-all.ru/3.15/library/functions.html#format), но также поддерживает смешивание спецификаторов %char с произвольным текстом.824825  Также была добавлена новая функция `currency()`, которая форматирует число в соответствии с настройками текущей локали.826827  (Автор: Georg Brandl.)828- Модуль [`mailbox`](https://python-all.ru/3.15/library/mailbox.html#module-mailbox) был значительно переписан, чтобы добавить возможность изменять почтовые ящики в дополнение к чтению. Новый набор классов, включающий `mbox`, `MH` и `Maildir`, используется для чтения почтовых ящиков и имеет метод `add(message)` для добавления сообщений, `remove(key)` для удаления сообщений и `lock()`/`unlock()` для блокировки/разблокировки почтового ящика. В следующем примере почтовый ящик в формате maildir преобразуется в формат mbox:829830  ```python831  import mailbox832833  # 'factory=None' использует email.Message.Message как класс, представляющий отдельные сообщения.834  # отдельные сообщения.835  src = mailbox.Maildir('maildir', factory=None)836  dest = mailbox.mbox('/tmp/mbox')837838  for msg in src:839      dest.add(msg)840  ```841842  (Автор: Gregory K. Johnson. Финансирование предоставлено программой Google Summer of Code 2005.)843- Новый модуль: модуль `msilib` позволяет создавать файлы Microsoft Installer `.msi` и CAB-файлы. Также включена некоторая поддержка чтения базы данных `.msi`. (Автор: Martin von Löwis.)844- Модуль `nis` теперь поддерживает доступ к доменам, отличным от системного домена по умолчанию, путём передачи аргумента *domain* в функции `nis.match()` и `nis.maps()`. (Автор: Ben Bell.)845- Функции `itemgetter()` и `attrgetter()` модуля [`operator`](https://python-all.ru/3.15/library/operator.html#module-operator) теперь поддерживают несколько полей. Вызов вида `operator.attrgetter('a', 'b')` вернёт функцию, которая получает атрибуты `a` и `b`. Сочетание этой новой возможности с параметром `key` метода `sort()` позволяет легко сортировать списки по нескольким полям. (Автор: Raymond Hettinger.)846- Модуль [`optparse`](https://python-all.ru/3.15/library/optparse.html#module-optparse) обновлён до версии 1.5.1 библиотеки Optik. Класс `OptionParser` получил атрибут `epilog` – строку, которая будет выводиться после сообщения справки, и метод `destroy()` для разрыва циклических ссылок, создаваемых объектом. (Автор: Greg Ward.)847- Модуль [`os`](https://python-all.ru/3.15/library/os.html#module-os) претерпел несколько изменений. Переменная `stat_float_times` теперь по умолчанию равна true, то есть [`os.stat()`](https://python-all.ru/3.15/library/os.html#os.stat) теперь возвращает значения времени в виде чисел с плавающей запятой. (Это не обязательно означает, что `os.stat()` будет возвращать время с точностью до долей секунды; не все системы поддерживают такую точность.)848849  Добавлены константы с именами [`os.SEEK_SET`](https://python-all.ru/3.15/library/os.html#os.SEEK_SET), [`os.SEEK_CUR`](https://python-all.ru/3.15/library/os.html#os.SEEK_CUR) и [`os.SEEK_END`](https://python-all.ru/3.15/library/os.html#os.SEEK_END); это параметры функции [`os.lseek()`](https://python-all.ru/3.15/library/os.html#os.lseek). Две новые константы для блокировки: [`os.O_SHLOCK`](https://python-all.ru/3.15/library/os.html#os.O_SHLOCK) и [`os.O_EXLOCK`](https://python-all.ru/3.15/library/os.html#os.O_EXLOCK).850851  Добавлены две новые функции: `wait3()` и `wait4()`. Они похожи на функцию `waitpid()`, которая ожидает завершения дочернего процесса и возвращает кортеж из идентификатора процесса и его статуса выхода, но `wait3()` и `wait4()` возвращают дополнительную информацию. `wait3()` не принимает идентификатор процесса на вход, поэтому она ожидает завершения любого дочернего процесса и возвращает кортеж из трёх элементов: *идентификатора процесса*, *статуса выхода*, *использования ресурсов*, как возвращается функцией [`resource.getrusage()`](https://python-all.ru/3.15/library/resource.html#resource.getrusage). `wait4(pid)` принимает идентификатор процесса. (Автор: Chad J. Schroeder.)852853  На FreeBSD функция [`os.stat()`](https://python-all.ru/3.15/library/os.html#os.stat) теперь возвращает время с наносекундным разрешением, а возвращаемый объект теперь имеет `st_gen` и `st_birthtime`. Атрибут `st_flags` также доступен, если платформа его поддерживает. (Авторы: Antti Louko и Diego Pettenò.)854- Отладчик Python, предоставляемый модулем [`pdb`](https://python-all.ru/3.15/library/pdb.html#module-pdb), теперь может хранить списки команд для выполнения при достижении точки останова и остановке выполнения. После создания точки останова #1 введите `commands 1` и введите серию команд для выполнения, завершив список командой `end`. Список команд может включать команды, возобновляющие выполнение, такие как `continue` или `next`. (Автор: Grégoire Dooms.)855- Модули [`pickle`](https://python-all.ru/3.15/library/pickle.html#module-pickle) и `cPickle` больше не принимают возвращаемое значение `None` от метода [`__reduce__()`](https://python-all.ru/3.15/library/pickle.html#object.__reduce__); метод теперь должен возвращать кортеж аргументов. Возможность возвращать `None` была объявлена устаревшей в Python 2.4, так что это завершает удаление этой возможности.856- The [`pkgutil`](https://python-all.ru/3.15/library/pkgutil.html#module-pkgutil) module, containing various utility functions for finding packages, was enhanced to support [**PEP 302**](https://python-all.ru/3.15/whatsnew/2.5.html)’s import hooks and now also works for packages stored in ZIP-format archives. (Contributed by Phillip J. Eby.)857- Набор тестов производительности pybench, созданный Marc-André Lemburg, теперь включён в каталог `Tools/pybench`. Набор pybench – это улучшение по сравнению с часто используемой программой `pystone.py`, поскольку pybench предоставляет более детальное измерение скорости интерпретатора. Он замеряет время отдельных операций, таких как вызовы функций, срезы кортежей, поиск методов и числовые операции, вместо того чтобы выполнять много разных операций и сводить результат к одному числу, как это делает `pystone.py`.858- Модуль `pyexpat` теперь использует версию 2.0 парсера Expat. (Автор: Trent Mick.)859- Класс [`Queue`](https://python-all.ru/3.15/library/queue.html#queue.Queue) из модуля `Queue` получил два новых метода. `join()` блокируется, пока все элементы очереди не будут извлечены и вся обработка элементов не завершится. Рабочие потоки вызывают другой новый метод, `task_done()`, чтобы сообщить о завершении обработки элемента. (Автор: Raymond Hettinger.)860- Старые модули `regex` и `regsub`, которые были объявлены устаревшими ещё в Python 2.0, наконец удалены. Другие удалённые модули: `statcache`, `tzparse`, `whrandom`.861- Также удалён каталог `lib-old`, который содержал древние модули, такие как `dircmp` и `ni`. `lib-old` не было в `sys.path` по умолчанию, так что если ваши программы явно не добавляли этот каталог в `sys.path`, это удаление не должно повлиять на ваш код.862- Модуль [`rlcompleter`](https://python-all.ru/3.15/library/rlcompleter.html#module-rlcompleter) больше не зависит от импорта модуля [`readline`](https://python-all.ru/3.15/library/readline.html#module-readline) и поэтому теперь работает на платформах, отличных от Unix. (Патч от Robert Kiendl.)863- Классы [`SimpleXMLRPCServer`](https://python-all.ru/3.15/library/xmlrpc.server.html#module-xmlrpc.server) и `DocXMLRPCServer` теперь имеют атрибут `rpc_paths`, который ограничивает операции XML-RPC ограниченным набором путей URL; по умолчанию разрешены только `'/'` и `'/RPC2'`. Установка `rpc_paths` в `None` или пустой кортеж отключает эту проверку путей.864- Модуль [`socket`](https://python-all.ru/3.15/library/socket.html#module-socket) теперь поддерживает сокеты `AF_NETLINK` в Linux, благодаря патчу от Philippe Biondi. Сокеты Netlink – это специфичный для Linux механизм взаимодействия между процессом в пространстве пользователя и кодом ядра; вводная статья о них находится по адресу [https://www.linuxjournal.com/article/7356](https://python-all.ru/3.15/whatsnew/2.5.html). В коде Python адреса netlink представляются в виде кортежа из двух целых чисел: `(pid, group_mask)`.865866  Два новых метода объектов сокетов, `recv_into(buffer)` и `recvfrom_into(buffer)`, сохраняют полученные данные в объекте, который поддерживает буферный протокол, вместо возврата данных в виде строки. Это означает, что данные можно помещать напрямую в массив или файл, отображённый в память.867868  Объекты сокетов также получили методы доступа `getfamily()`, `gettype()` и `getproto()` для получения значений семейства, типа и протокола сокета.869- Новый модуль: модуль `spwd` предоставляет функции для доступа к базе данных теневых паролей в системах, поддерживающих теневые пароли.870- [`struct`](https://python-all.ru/3.15/library/struct.html#module-struct) теперь работает быстрее, поскольку компилирует строки формата в объекты `Struct` с методами `pack()` и `unpack()`. Это похоже на то, как модуль [`re`](https://python-all.ru/3.15/library/re.html#module-re) позволяет создавать скомпилированные объекты регулярных выражений. По-прежнему можно использовать функции уровня модуля `pack()` и `unpack()`; они будут создавать объекты `Struct` и кэшировать их. Или можно напрямую использовать экземпляры `Struct`:871872  ```python873  s = struct.Struct('ih3s')874875  data = s.pack(1972, 187, 'abc')876  year, number, name = s.unpack(data)877  ```878879  Также можно упаковывать и распаковывать данные в буферные объекты и из них напрямую с помощью методов `pack_into(buffer, offset, v1, v2, ...)` и `unpack_from(buffer, offset)`. Это позволяет сохранять данные непосредственно в массив или файл, отображённый в память.880881  (Объекты `Struct` были реализованы Bob Ippolito на спринте NeedForSpeed. Поддержка буферных объектов была добавлена Martin Blais, также на спринте NeedForSpeed.)882- Разработчики Python перешли с CVS на Subversion в процессе разработки версии 2.5. Информация о точной версии сборки доступна в виде переменной `sys.subversion` – кортежа из трёх элементов `(interpreter-name, branch-name, revision-range)`. Например, на момент написания этого текста моя копия 2.5 сообщала `('CPython', 'trunk', '45313:45315')`.883884  Эта информация также доступна для C-расширений через функцию [`Py_GetBuildInfo()`](https://python-all.ru/3.15/c-api/interp-lifecycle.html#c.Py_GetBuildInfo), которая возвращает строку с информацией о сборке, например: `"trunk:45355:45356M, Apr 13 2006, 07:42:19"`. (Автор: Barry Warsaw.)885- Ещё одна новая функция, [`sys._current_frames()`](https://python-all.ru/3.15/library/sys.html#sys._current_frames), возвращает текущие стековые кадры для всех запущенных потоков в виде словаря, отображающего идентификаторы потоков в самый верхний стековый кадр, активный в этом потоке на момент вызова функции. (Автор: Tim Peters.)886- Класс `TarFile` в модуле [`tarfile`](https://python-all.ru/3.15/library/tarfile.html#module-tarfile) теперь имеет метод `extractall()`, который извлекает все элементы из архива в текущий рабочий каталог. Также можно указать другой каталог в качестве целевого для извлечения и распаковать только подмножество элементов архива.887888  Тип сжатия для tar-файла, открытого в потоковом режиме, теперь может автоматически определяться с помощью режима `'r|*'`. (Автор: Lars Gustäbel.)889- Модуль [`threading`](https://python-all.ru/3.15/library/threading.html#module-threading) теперь позволяет задавать размер стека, используемый при создании новых потоков. Функция `stack_size([*size*])` возвращает текущий настроенный размер стека, а передача необязательного параметра *size* устанавливает новое значение. Не все платформы поддерживают изменение размера стека, но Windows, POSIX-потоки и OS/2 поддерживают. (Автор: Andrew MacIntyre.)890- Модуль [`unicodedata`](https://python-all.ru/3.15/library/unicodedata.html#module-unicodedata) обновлён до использования версии 4.1.0 базы данных символов Unicode. Версия 3.2.0 требуется некоторыми спецификациями, поэтому она всё ещё доступна как [`unicodedata.ucd_3_2_0`](https://python-all.ru/3.15/library/unicodedata.html#unicodedata.ucd_3_2_0).891- Новый модуль: модуль [`uuid`](https://python-all.ru/3.15/library/uuid.html#module-uuid) генерирует универсальные уникальные идентификаторы (UUID) в соответствии с [**RFC 4122**](https://python-all.ru/3.15/whatsnew/2.5.html). RFC определяет несколько различных версий UUID, которые генерируются из начальной строки, из системных свойств или полностью случайным образом. Этот модуль содержит класс `UUID` и функции с именами `uuid1()`, `uuid3()`, `uuid4()` и `uuid5()` для генерации различных версий UUID. (UUID версии 2 не определены в [**RFC 4122**](https://python-all.ru/3.15/whatsnew/2.5.html) и не поддерживаются этим модулем.)892893  ```python894  >>> import uuid895  >>> # создать UUID на основе идентификатора хоста и текущего времени896  >>> uuid.uuid1()897  UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')898899  >>> # создать UUID с использованием MD5-хеша UUID пространства имён и имени900  >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')901  UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')902903  >>> # создать случайный UUID904  >>> uuid.uuid4()905  UUID('16fd2706-8baf-433b-82eb-8c7fada847da')906907  >>> # создать UUID с использованием SHA-1-хеша UUID пространства имён и имени908  >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')909  UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')910  ```911912  (Автор: Ka-Ping Yee.)913- Типы `WeakKeyDictionary` и `WeakValueDictionary` модуля [`weakref`](https://python-all.ru/3.15/library/weakref.html#module-weakref) получили новые методы для перебора слабых ссылок, содержащихся в словаре. Методы `iterkeyrefs()` и `keyrefs()` были добавлены в `WeakKeyDictionary`, а `itervaluerefs()` и `valuerefs()` – в `WeakValueDictionary`. (Автор: Fred L. Drake, Jr.)914- Модуль [`webbrowser`](https://python-all.ru/3.15/library/webbrowser.html#module-webbrowser) получил ряд улучшений. Теперь его можно использовать как скрипт с помощью `python -m webbrowser`, принимая URL в качестве аргумента; есть несколько опций для управления поведением (`-n` для нового окна браузера, `-t` для новой вкладки). Для поддержки этого были добавлены новые функции уровня модуля: `open_new()` и `open_new_tab()`. Функция [`open()`](https://python-all.ru/3.15/library/functions.html#open) модуля поддерживает дополнительную возможность – параметр *autoraise*, который указывает, следует ли поднимать открытое окно, когда это возможно. В список поддерживаемых браузеров были добавлены Firefox, Opera, Konqueror и elinks. (Авторы: Oleg Broytmann и Georg Brandl.)915- Модуль [`xmlrpclib`](https://python-all.ru/3.15/library/xmlrpc.client.html#module-xmlrpc.client) теперь поддерживает возврат объектов [`datetime`](https://python-all.ru/3.15/library/datetime.html#datetime.datetime) для типа даты XML-RPC. Передайте `use_datetime=True` функции [`loads()`](https://python-all.ru/3.15/library/xmlrpc.client.html#xmlrpc.client.loads) или классу `Unmarshaller`, чтобы включить эту возможность. (Автор: Skip Montanaro.)916- Модуль [`zipfile`](https://python-all.ru/3.15/library/zipfile.html#module-zipfile) теперь поддерживает формат ZIP64, то есть архив .zip может быть больше 4 ГиБ и содержать отдельные файлы размером более 4 ГиБ. (Автор: Ronald Oussoren.)917- Объекты `Compress` и `Decompress` модуля [`zlib`](https://python-all.ru/3.15/library/zlib.html#module-zlib) теперь поддерживают метод [`copy()`](https://python-all.ru/3.15/library/copy.html#module-copy), который создает копию внутреннего состояния объекта и возвращает новый объект `Compress` или `Decompress`. (Автор: Chris AtLee.)918919### Пакет ctypes920921Пакет [`ctypes`](https://python-all.ru/3.15/library/ctypes.html#module-ctypes), написанный Томасом Хеллером, был добавлен в стандартную библиотеку. `ctypes` позволяет вызывать произвольные функции в разделяемых библиотеках или DLL. Постоянные пользователи могут помнить модуль `dl`, который предоставляет функции для загрузки разделяемых библиотек и вызова в них функций. Пакет `ctypes` гораздо навороченнее.922923Чтобы загрузить разделяемую библиотеку или DLL, необходимо создать экземпляр класса `CDLL` и указать имя или путь к разделяемой библиотеке или DLL. После этого можно вызывать произвольные функции, обращаясь к ним как к атрибутам объекта `CDLL`.924925```python926import ctypes927928libc = ctypes.CDLL('libc.so.6')929result = libc.printf("Line of output\n")930```931932Предоставляются конструкторы типов для различных типов C: `c_int()`, `c_float()`, `c_double()`, `c_char_p()` (эквивалентно char\*) и так далее. В отличие от типов Python, версии C все изменяемы; можно присвоить их атрибуту `value`, чтобы изменить обернутое значение. Целые числа и строки Python будут автоматически преобразованы в соответствующие типы C, но для других типов необходимо вызывать правильный конструктор типа. (И я имею в виду *необходимо*; если ошибиться, это часто приводит к падению интерпретатора с ошибкой сегментации.)933934Не следует использовать `c_char_p()` с строкой Python, если функция C будет изменять область памяти, поскольку строки Python считаются неизменяемыми; нарушение этого правила приведет к труднообъяснимым ошибкам. Когда требуется изменяемая область памяти, используйте `create_string_buffer()`:935936```python937s = "this is a string"938buf = ctypes.create_string_buffer(s)939libc.strfry(buf)940```941942Предполагается, что функции C возвращают целые числа, но можно установить атрибут `restype` объекта функции, чтобы изменить это:943944```python945>>> libc.atof('2.71828')946-1783957616947>>> libc.atof.restype = ctypes.c_double948>>> libc.atof('2.71828')9492.71828950```951952[`ctypes`](https://python-all.ru/3.15/library/ctypes.html#module-ctypes) также предоставляет обертку для C API Python в виде объекта `ctypes.pythonapi`. Этот объект *не* освобождает глобальную блокировку интерпретатора перед вызовом функции, поскольку блокировка должна быть удержана при вызове кода интерпретатора. Существует конструктор типа [`py_object`](https://python-all.ru/3.15/library/ctypes.html#ctypes.py_object), который создает указатель [PyObject](https://python-all.ru/3.15/c-api/structures.html#c.PyObject)\*. Простой пример использования:953954```python955import ctypes956957d = {}958ctypes.pythonapi.PyObject_SetItem(ctypes.py_object(d),959          ctypes.py_object("abc"),  ctypes.py_object(1))960# d теперь содержит {'abc', 1}.961```962963Не забывайте использовать [`py_object()`](https://python-all.ru/3.15/library/ctypes.html#ctypes.py_object); если его пропустить, получите ошибку сегментации.964965[`ctypes`](https://python-all.ru/3.15/library/ctypes.html#module-ctypes) существует уже некоторое время, но люди всё ещё пишут и распространяют собственноручно написанные модули расширения, потому что нельзя полагаться на наличие `ctypes`. Возможно, разработчики начнут писать обертки Python поверх библиотек, доступных через `ctypes`, вместо модулей расширения, теперь, когда `ctypes` включен в ядро Python.966967> **См. также**968>969> **[https://web.archive.org/web/20180410025338/http://starship.python.net/crew/theller/ctypes/](https://python-all.ru/3.15/whatsnew/2.5.html)**970>971> Веб-страница ctypes до включения в стандартную библиотеку, с учебным пособием, справочником и FAQ.972>973> Документация для модуля [`ctypes`](https://python-all.ru/3.15/library/ctypes.html#module-ctypes).974975### Пакет ElementTree976977Подмножество библиотеки ElementTree Фредрика Лунда для обработки XML было добавлено в стандартную библиотеку как `xml.etree`. Доступны модули `ElementTree`, `ElementPath` и `ElementInclude` из ElementTree 1.2.6. Также включен ускоряющий модуль `cElementTree`.978979Остальная часть этого раздела даст краткий обзор использования ElementTree. Полная документация по ElementTree доступна по адресу [https://web.archive.org/web/20201124024954/http://effbot.org/zone/element-index.htm](https://python-all.ru/3.15/whatsnew/2.5.html).980981ElementTree представляет XML-документ в виде дерева узлов-элементов. Текстовое содержимое документа хранится в атрибутах `text` и `tail`. (Это одно из главных различий между ElementTree и объектной моделью документа (DOM); в DOM существует много разных типов узлов, включая `TextNode`.)982983Наиболее часто используемая функция разбора – `parse()`, которая принимает строку (предположительно содержащую имя файла) или файлоподобный объект и возвращает экземпляр `ElementTree`:984985```python986from xml.etree import ElementTree as ET987988tree = ET.parse('ex-1.xml')989990feed = urllib.urlopen(991          'http://planet.python.org/rss10.xml')992tree = ET.parse(feed)993```994995Получив экземпляр `ElementTree`, можно вызвать его метод `getroot()`, чтобы получить корневой узел `Element`.996997Существует также функция `XML()`, которая принимает строковый литерал и возвращает узел `Element` (не `ElementTree`). Эта функция предоставляет аккуратный способ включения XML-фрагментов, приближаясь к удобству XML-литерала:998999```python1000svg = ET.XML("""<svg width="10px" version="1.0">1001             </svg>""")1002svg.set('height', '320px')1003svg.append(elem1)1004```10051006Каждый XML-элемент поддерживает некоторые методы доступа, похожие на словарные и на списковые. Словарные операции используются для доступа к значениям атрибутов, а списковые – для доступа к дочерним узлам.10071008| Операция | Результат |1009| --- | --- |1010| `elem[n]` | Возвращает n-й дочерний элемент. |1011| `elem[m:n]` | Возвращает список дочерних элементов с m-го по n-й. |1012| `len(elem)` | Возвращает количество дочерних элементов. |1013| `list(elem)` | Возвращает список дочерних элементов. |1014| `elem.append(elem2)` | Добавляет *elem2* как дочерний элемент. |1015| `elem.insert(index, elem2)` | Вставляет *elem2* в указанную позицию. |1016| `del elem[n]` | Удаляет n-й дочерний элемент. |1017| `elem.keys()` | Возвращает список имён атрибутов. |1018| `elem.get(name)` | Возвращает значение атрибута *name*. |1019| `elem.set(name, value)` | Устанавливает новое значение для атрибута *name*. |1020| `elem.attrib` | Извлекает словарь, содержащий атрибуты. |1021| `del elem.attrib[name]` | Удаляет атрибут *name*. |10221023Комментарии и инструкции по обработке также представлены как узлы `Element`. Чтобы проверить, является ли узел комментарием или инструкцией по обработке:10241025```python1026if elem.tag is ET.Comment:1027    ...1028elif elem.tag is ET.ProcessingInstruction:1029    ...1030```10311032Чтобы сгенерировать XML-вывод, следует вызвать метод `ElementTree.write()`. Как и `parse()`, он может принимать как строку, так и файлоподобный объект:10331034```python1035# Кодировка: US-ASCII1036tree.write('output.xml')10371038# Кодировка: UTF-81039f = open('output.xml', 'w')1040tree.write(f, encoding='utf-8')1041```10421043(Предупреждение: кодировка, используемая по умолчанию для вывода – ASCII. Для обычной работы с XML, где имя элемента может содержать произвольные символы Unicode, ASCII – не очень полезная кодировка, так как она вызовет исключение, если имя элемента содержит символы со значениями больше 127. Поэтому лучше указать другую кодировку, например UTF-8, которая может обрабатывать любые символы Unicode.)10441045Этот раздел содержит лишь частичное описание интерфейсов ElementTree. Пожалуйста, прочитайте официальную документацию пакета для получения более подробной информации.10461047> **См. также**1048>1049> **[https://web.archive.org/web/20201124024954/http://effbot.org/zone/element-index.htm](https://python-all.ru/3.15/whatsnew/2.5.html)**1050>1051> Официальная документация для ElementTree.10521053### Пакет hashlib10541055Новый модуль [`hashlib`](https://python-all.ru/3.15/library/hashlib.html#module-hashlib), написанный Gregory P. Smith, был добавлен для замены модулей `md5` и `sha`. `hashlib` добавляет поддержку дополнительных безопасных хэшей (SHA-224, SHA-256, SHA-384 и SHA-512). При наличии модуль использует OpenSSL для быстрых оптимизированных под платформу реализаций алгоритмов.10561057Старые модули `md5` и `sha` всё ещё существуют как обёртки вокруг hashlib для сохранения обратной совместимости. Интерфейс нового модуля очень близок к интерфейсу старых модулей, но не идентичен. Наиболее существенное отличие заключается в том, что функции-конструкторы для создания новых хэширующих объектов называются по-другому.10581059```python1060# Старые версии1061h = md5.md5()1062h = md5.new()10631064# Новая версия1065h = hashlib.md5()10661067# Старые версии1068h = sha.sha()1069h = sha.new()10701071# Новая версия1072h = hashlib.sha1()10731074# Хэши, которые ранее были недоступны1075h = hashlib.sha224()1076h = hashlib.sha256()1077h = hashlib.sha384()1078h = hashlib.sha512()10791080# Альтернативная форма1081h = hashlib.new('md5')          # Указать алгоритм в виде строки1082```10831084После создания хэш-объекта его методы остаются теми же: `update(string)` хэширует указанную строку в текущее состояние дайджеста, `digest()` и `hexdigest()` возвращают значение дайджеста в виде двоичной строки или строки шестнадцатеричных цифр, а [`copy()`](https://python-all.ru/3.15/library/copy.html#module-copy) возвращает новый хэширующий объект с тем же состоянием дайджеста.10851086> **См. также**1087>1088> Документация для модуля [`hashlib`](https://python-all.ru/3.15/library/hashlib.html#module-hashlib).10891090### Пакет sqlite310911092Модуль pysqlite ([https://www.pysqlite.org](https://python-all.ru/3.15/whatsnew/2.5.html)), обёртка для встраиваемой базы данных SQLite, был добавлен в стандартную библиотеку под именем пакета [`sqlite3`](https://python-all.ru/3.15/library/sqlite3.html#module-sqlite3).10931094SQLite – это библиотека на C, которая предоставляет легковесную дисковую базу данных, не требующую отдельного серверного процесса, и позволяет обращаться к базе данных с помощью нестандартного варианта языка SQL. Некоторые приложения могут использовать SQLite для внутреннего хранения данных. Также можно создать прототип приложения на SQLite, а затем перенести код на более крупную базу данных, например PostgreSQL или Oracle.10951096pysqlite был написан Gerhard Häring и предоставляет SQL-интерфейс, совместимый со спецификацией DB-API 2.0, описанной в [**PEP 249**](https://python-all.ru/3.15/whatsnew/2.5.html).10971098Если вы компилируете исходный код Python самостоятельно, учтите, что дерево исходников не включает код SQLite, только модуль-обёртку. Вам потребуется установить библиотеки и заголовочные файлы SQLite перед компиляцией Python, и процесс сборки скомпилирует модуль, когда необходимые заголовочные файлы будут доступны.10991100Чтобы использовать модуль, сначала необходимо создать объект `Connection`, который представляет базу данных. Здесь данные будут храниться в файле `/tmp/example`:11011102```python1103conn = sqlite3.connect('/tmp/example')1104```11051106Также можно указать специальное имя `:memory:` для создания базы данных в оперативной памяти.11071108После получения `Connection` можно создать объект `Cursor` и вызвать его метод `execute()` для выполнения SQL-команд:11091110```python1111c = conn.cursor()11121113# Создать таблицу1114c.execute('''create table stocks1115(date text, trans text, symbol text,1116 qty real, price real)''')11171118# Вставить строку данных1119c.execute("""insert into stocks1120          values ('2006-01-05','BUY','RHAT',100,35.14)""")1121```11221123Обычно вашим SQL-операциям потребуется использовать значения из переменных Python. Не следует собирать запрос с помощью строковых операций Python, потому что это небезопасно; это делает вашу программу уязвимой для SQL-инъекций.11241125Вместо этого используйте подстановку параметров DB-API. Вставьте `?` в качестве заполнителя везде, где нужно использовать значение, а затем передайте кортеж значений в качестве второго аргумента методу `execute()` курсора. (Другие модули баз данных могут использовать другой заполнитель, например `%s` или `:1`.) Например:11261127```python1128# Никогда не делайте этого – это небезопасно!1129symbol = 'IBM'1130c.execute("... where symbol = '%s'" % symbol)11311132# Вместо этого сделайте так1133t = (symbol,)1134c.execute('select * from stocks where symbol=?', t)11351136# Более крупный пример1137for t in (('2006-03-28', 'BUY', 'IBM', 1000, 45.00),1138          ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),1139          ('2006-04-06', 'SELL', 'IBM', 500, 53.00),1140         ):1141    c.execute('insert into stocks values (?,?,?,?,?)', t)1142```11431144Чтобы извлечь данные после выполнения оператора SELECT, можно либо рассматривать курсор как итератор, вызвать метод `fetchone()` курсора для получения одной подходящей строки, либо вызвать `fetchall()`, чтобы получить список подходящих строк.11451146В этом примере используется форма итератора:11471148```python1149>>> c = conn.cursor()1150>>> c.execute('select * from stocks order by price')1151>>> for row in c:1152...    print row1153...1154(u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001)1155(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)1156(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)1157(u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)1158>>>1159```11601161Для получения дополнительной информации о диалекте SQL, поддерживаемом SQLite, см. [https://www.sqlite.org](https://python-all.ru/3.15/whatsnew/2.5.html).11621163> **См. также**1164>1165> **[https://www.pysqlite.org](https://python-all.ru/3.15/whatsnew/2.5.html)**1166>1167> Веб-страница pysqlite.1168>1169> **[https://www.sqlite.org](https://python-all.ru/3.15/whatsnew/2.5.html)**1170>1171> Веб-страница SQLite; документация описывает синтаксис и доступные типы данных для поддерживаемого диалекта SQL.1172>1173> Документация для модуля [`sqlite3`](https://python-all.ru/3.15/library/sqlite3.html#module-sqlite3).1174>1175> **[**PEP 249**](https://python-all.ru/3.15/whatsnew/2.5.html) – спецификация API баз данных 2.0**1176>1177> PEP написан Марком-Андре Лембургом.11781179### Пакет wsgiref11801181Web Server Gateway Interface (WSGI) v1.0 определяет стандартный интерфейс между веб-серверами и веб-приложениями Python. Спецификация описана в [**PEP 333**](https://python-all.ru/3.15/whatsnew/2.5.html). Пакет [`wsgiref`](https://python-all.ru/3.15/library/wsgiref.html#module-wsgiref) – это эталонная реализация WSGI.11821183Пакет включает базовый HTTP-сервер, который запускает WSGI-приложение; этот сервер полезен для отладки, но не предназначен для промышленного использования. Для настройки сервера достаточно нескольких строк кода:11841185```python1186from wsgiref import simple_server11871188wsgi_app = ...11891190host = ''1191port = 80001192httpd = simple_server.make_server(host, port, wsgi_app)1193httpd.serve_forever()1194```11951196> **См. также**1197>1198> **[https://web.archive.org/web/20160331090247/http://wsgi.readthedocs.org/en/latest/](https://python-all.ru/3.15/whatsnew/2.5.html)**1199>1200> Центральный веб-сайт с ресурсами, связанными с WSGI.1201>1202> **[**PEP 333**](https://python-all.ru/3.15/whatsnew/2.5.html) - Интерфейс шлюза веб-сервера Python v1.0**1203>1204> PEP написан Филиппом Дж. Эби.12051206## Изменения в сборке и C API12071208Изменения процесса сборки Python и C API включают:12091210- Дерево исходного кода Python было перенесено из CVS в Subversion в ходе сложной процедуры миграции, которую курировал и безупречно выполнил Martin von Löwis. Эта процедура была разработана как [**PEP 347**](https://python-all.ru/3.15/whatsnew/2.5.html).1211- Компания Coverity, которая продаёт инструмент анализа исходного кода Prevent, предоставила результаты проверки исходного кода Python. Анализ выявил около 60 ошибок, которые были быстро исправлены. Многие из ошибок были проблемами подсчёта ссылок, часто возникавшими в коде обработки ошибок. Статистику см. на [https://scan.coverity.com](https://python-all.ru/3.15/whatsnew/2.5.html).1212- Самое большое изменение в C API произошло из-за [**PEP 353**](https://python-all.ru/3.15/whatsnew/2.5.html), который модифицирует интерпретатор, чтобы использовать определение типа [`Py_ssize_t`](https://python-all.ru/3.15/c-api/intro.html#c.Py_ssize_t) вместо int. Обсуждение этого изменения см. в разделе [PEP 353: Использование ssize\_t в качестве типа индекса](https://python-all.ru/3.15/whatsnew/2.5.html#pep-353).1213- Конструкция компилятора байт-кода сильно изменилась: он больше не генерирует байт-код обходом дерева разбора. Вместо этого дерево разбора преобразуется в абстрактное синтаксическое дерево (AST), и именно AST обходится для генерации байт-кода.12141215  Код на Python может получить объекты AST, используя встроенную функцию [`compile()`](https://python-all.ru/3.15/library/functions.html#compile) и указав `_ast.PyCF_ONLY_AST` в качестве значения параметра *flags*:12161217  ```python1218  from _ast import PyCF_ONLY_AST1219  ast = compile("""a=01220  for i in range(10):1221      a += i1222  """, "<string>", 'exec', PyCF_ONLY_AST)12231224  assignment = ast.body[0]1225  for_loop = ast.body[1]1226  ```12271228  Официальной документации для кода AST пока нет, но [**PEP 339**](https://python-all.ru/3.15/whatsnew/2.5.html) описывает проект. Чтобы начать изучение кода, прочитайте определения различных узлов AST в `Parser/Python.asdl`. Python-скрипт читает этот файл и генерирует набор определений структур C в `Include/Python-ast.h`. Функции `PyParser_ASTFromString()` и `PyParser_ASTFromFile()`, определённые в `Include/pythonrun.h`, принимают исходный код Python и возвращают корень AST, представляющего содержимое. Затем этот AST может быть преобразован в объект кода с помощью `PyAST_Compile()`. Для получения дополнительной информации читайте исходный код и задавайте вопросы в python-dev.12291230  Код AST разработан под руководством Джереми Хилтона, а реализован (в алфавитном порядке) Бреттом Кэнноном, Ником Коглан, Грантом Эдвардсом, Джоном Эресманом, Куртом Кайзером, Нилом Норвитцем, Тимом Питерсом, Армином Риго и Нилом Шеменауэром, а также участниками многочисленных AST-спринтов на конференциях, таких как PyCon.1231- Патч Эвана Джонса к obmalloc, впервые описанный в докладе на PyCon DC 2005, был применён. Python 2.4 выделял маленькие объекты в аренах размером 256 КБ, но никогда не освобождал арены. С этим патчем Python освобождает арены, когда они пусты. Чистый эффект заключается в том, что на некоторых платформах при выделении большого количества объектов потребление памяти Python может фактически уменьшиться при их удалении, и память может быть возвращена операционной системе. (Реализовано Эваном Джонсом, доработано Тимом Питерсом.)12321233  Обратите внимание, что это изменение означает, что модули расширения должны быть более осторожными при выделении памяти. Python API содержит множество различных функций для выделения памяти, сгруппированных в семейства. Например, [`PyMem_Malloc()`](https://python-all.ru/3.15/c-api/memory.html#c.PyMem_Malloc), [`PyMem_Realloc()`](https://python-all.ru/3.15/c-api/memory.html#c.PyMem_Realloc) и [`PyMem_Free()`](https://python-all.ru/3.15/c-api/memory.html#c.PyMem_Free) – одно семейство, выделяющее сырую память, а [`PyObject_Malloc()`](https://python-all.ru/3.15/c-api/memory.html#c.PyObject_Malloc), [`PyObject_Realloc()`](https://python-all.ru/3.15/c-api/memory.html#c.PyObject_Realloc) и [`PyObject_Free()`](https://python-all.ru/3.15/c-api/memory.html#c.PyObject_Free) – другое семейство, предназначенное для создания объектов Python.12341235  Ранее все эти семейства сводились к функциям `malloc()` и `free()` платформы. Это означало, что не имело значения, если вы ошибались и выделяли память функцией `PyMem`, а освобождали функцией `PyObject`. С изменениями obmalloc в версии 2.5 эти семейства теперь делают разные вещи, и несоответствие, вероятно, приведёт к segfault. Следует тщательно тестировать свои модули расширения C с Python 2.5.1236- Встроенные типы set теперь имеют официальный C API. Вызывайте [`PySet_New()`](https://python-all.ru/3.15/c-api/set.html#c.PySet_New) и [`PyFrozenSet_New()`](https://python-all.ru/3.15/c-api/set.html#c.PyFrozenSet_New) для создания нового множества, [`PySet_Add()`](https://python-all.ru/3.15/c-api/set.html#c.PySet_Add) и [`PySet_Discard()`](https://python-all.ru/3.15/c-api/set.html#c.PySet_Discard) для добавления и удаления элементов, а [`PySet_Contains()`](https://python-all.ru/3.15/c-api/set.html#c.PySet_Contains) и [`PySet_Size()`](https://python-all.ru/3.15/c-api/set.html#c.PySet_Size) для проверки состояния множества. (Автор: Raymond Hettinger.)1237- Код на C теперь может получать информацию о точной ревизии интерпретатора Python, вызывая функцию [`Py_GetBuildInfo()`](https://python-all.ru/3.15/c-api/interp-lifecycle.html#c.Py_GetBuildInfo), которая возвращает строку с информацией о сборке, например: `"trunk:45355:45356M, Apr 13 2006, 07:42:19"`. (Автор: Barry Warsaw.)1238- Два новых макроса могут использоваться для обозначения C-функций, локальных для текущего файла, чтобы можно было использовать более быстрый механизм вызова. [`Py_LOCAL`](https://python-all.ru/3.15/c-api/intro.html#c.Py_LOCAL) объявляет функцию как возвращающую значение указанного *типа* и использует квалификатор быстрого вызова. [`Py_LOCAL_INLINE`](https://python-all.ru/3.15/c-api/intro.html#c.Py_LOCAL_INLINE) делает то же самое, а также запрашивает встраивание функции. Если макрос `PY_LOCAL_AGGRESSIVE` определён до включения `python.h`, для модуля включается набор более агрессивных оптимизаций; следует провести бенчмаркинг, чтобы выяснить, действительно ли эти оптимизации ускоряют код. (Автор: Fredrik Lundh на спринте NeedForSpeed.)1239- `PyErr_NewException(name, base, dict)` теперь может принимать кортеж базовых классов в качестве аргумента *base*. (Автор: Georg Brandl.)1240- Функция `PyErr_Warn()` для выдачи предупреждений теперь устарела в пользу `PyErr_WarnEx(category, message, stacklevel)`, которая позволяет указать количество кадров стека, разделяющих эту функцию и вызывающую. *stacklevel* равный 1 – это функция, вызывающая [`PyErr_WarnEx()`](https://python-all.ru/3.15/c-api/exceptions.html#c.PyErr_WarnEx), 2 – функция выше, и так далее. (Добавлено Нилом Норвитцем.)1241- Интерпретатор CPython по-прежнему написан на C, но теперь код может быть скомпилирован компилятором C++ без ошибок. (Реализовано Энтони Бакстером, Мартином фон Лёвисом, Скипом Монтанаро.)1242- Функция `PyRange_New()` была удалена. Она никогда не была документирована, никогда не использовалась в ядре и имела опасно слабую проверку ошибок. В маловероятном случае, если ваши расширения использовали её, её можно заменить чем-то вроде следующего:12431244  ```python1245  range = PyObject_CallFunction((PyObject*) &PyRange_Type, "lll",1246                                start, stop, step);1247  ```12481249### Изменения, специфичные для платформ12501251- MacOS X (10.3 и выше): динамическая загрузка модулей теперь использует функцию `dlopen()` вместо функций, специфичных для MacOS.1252- MacOS X: в скрипт **configure** добавлен флаг `--enable-universalsdk`, который компилирует интерпретатор как универсальный бинарный файл, способный работать как на процессорах PowerPC, так и Intel. (Автор: Ronald Oussoren; [bpo-2573](https://python-all.ru/3.15/whatsnew/2.5.html).)1253- Windows: `.dll` больше не поддерживается как расширение имени файла для модулей расширения. `.pyd` теперь единственное расширение имени файла, которое будет искаться.12541255## Перенос на Python 2.512561257В этом разделе перечислены описанные ранее изменения, которые могут потребовать изменения кода:12581259- ASCII теперь является кодировкой по умолчанию для модулей. Теперь это синтаксическая ошибка, если модуль содержит строковые литералы с 8-битными символами, но не имеет объявления кодировки. В Python 2.4 это вызывало предупреждение, а не синтаксическую ошибку.1260- Ранее атрибут `gi_frame` генератора всегда был объектом frame. Благодаря изменениям [**PEP 342**](https://python-all.ru/3.15/whatsnew/2.5.html), описанным в разделе [PEP 342: Новые возможности генераторов](https://python-all.ru/3.15/whatsnew/2.5.html#pep-342), теперь `gi_frame` может быть `None`.1261- Новое предупреждение [`UnicodeWarning`](https://python-all.ru/3.15/library/exceptions.html#UnicodeWarning) возникает при попытке сравнить строку Unicode и 8-битную строку, которую невозможно преобразовать в Unicode с использованием кодировки ASCII по умолчанию. Ранее такие сравнения вызывали исключение [`UnicodeDecodeError`](https://python-all.ru/3.15/library/exceptions.html#UnicodeDecodeError).1262- Библиотека: модуль [`csv`](https://python-all.ru/3.15/library/csv.html#module-csv) теперь более строг к многострочным полям в кавычках. Если файлы содержат символы новой строки внутри полей, входные данные следует разбивать на строки таким образом, чтобы сохранить символы новой строки.1263- Библиотека: функция [`format()`](https://python-all.ru/3.15/library/functions.html#format) модуля [`locale`](https://python-all.ru/3.15/library/locale.html#module-locale) ранее принимала любую строку, если в ней встречался не более одного спецификатора %char. В Python 2.5 аргумент должен содержать ровно один спецификатор %char без окружающего текста.1264- Библиотека: модули [`pickle`](https://python-all.ru/3.15/library/pickle.html#module-pickle) и `cPickle` больше не принимают возвращаемое значение `None` от метода [`__reduce__()`](https://python-all.ru/3.15/library/pickle.html#object.__reduce__); метод должен возвращать кортеж аргументов. Модули также больше не принимают устаревший именованный параметр *bin*.1265- Библиотека: классы [`SimpleXMLRPCServer`](https://python-all.ru/3.15/library/xmlrpc.server.html#module-xmlrpc.server) и `DocXMLRPCServer` теперь имеют атрибут `rpc_paths`, который ограничивает операции XML-RPC заданным набором путей URL; по умолчанию разрешены только `'/'` и `'/RPC2'`. Установка `rpc_paths` в `None` или пустой кортеж отключает проверку пути.1266- C API: многие функции теперь используют [`Py_ssize_t`](https://python-all.ru/3.15/c-api/intro.html#c.Py_ssize_t) вместо int, чтобы обеспечить обработку большего объёма данных на 64-разрядных машинах. Расширениям может потребоваться аналогичное изменение, чтобы избежать предупреждений и поддерживать 64-разрядные машины. См. раздел [PEP 353: Использование ssize\_t в качестве типа индекса](https://python-all.ru/3.15/whatsnew/2.5.html#pep-353) для обсуждения этого изменения.1267- C API: изменения obmalloc означают, что нужно быть внимательным и не смешивать использование семейств функций `PyMem_*` и `PyObject_*`. Память, выделенная с помощью `*_Malloc` одного семейства, должна освобождаться с помощью `*_Free` соответствующего семейства.12681269## Благодарности12701271Автор хотел бы поблагодарить следующих людей за предложения, исправления и помощь с различными черновиками этой статьи: Georg Brandl, Nick Coghlan, Phillip J. Eby, Lars Gustäbel, Raymond Hettinger, Ralf W. Grosse-Kunstleve, Kent Johnson, Iain Lowe, Martin von Löwis, Fredrik Lundh, Andrew McNamara, Skip Montanaro, Gustavo Niemeyer, Paul Prescod, James Pryor, Mike Rovner, Scott Weikart, Barry Warsaw, Thomas Wouters.1272