2.0.md
1> **Источник:** https://python-all.ru/3.1/whatsnew/2.0.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Что нового в Python 2.089| Автор: | A.M. Kuchling и Moshe Zadka |10| --- | --- |1112## Введение1314Новый выпуск Python, версия 2.0, был выпущен 16 октября 2000 года. В этой статье рассматриваются захватывающие новые возможности версии 2.0, освещаются некоторые другие полезные изменения и указываются несколько несовместимых изменений, которые могут потребовать переписывания кода.1516Разработка Python никогда не прекращается полностью между релизами – в неё постоянно поступает непрерывный поток исправлений ошибок и улучшений. В версию 2.0 вошло множество мелких исправлений, несколько оптимизаций, дополнительные строки документации и более качественные сообщения об ошибках; перечислить их все невозможно, но они, безусловно, важны. Если хотите увидеть полный список, обратитесь к общедоступным журналам CVS. Этот прогресс стал возможен благодаря пяти разработчикам, работающим в PythonLabs, которые теперь получают зарплату за то, что целыми днями исправляют ошибки, а также благодаря улучшению коммуникации после перехода на SourceForge.1718## Что насчёт Python 1.6?1920Python 1.6 можно считать релизом Python по договорным обязательствам. После того как основная команда разработчиков покинула CNRI в мае 2000 года, CNRI потребовала создать релиз 1.6, содержащий всю работу над Python, которая была выполнена в CNRI. Таким образом, Python 1.6 представляет состояние дерева CVS по состоянию на май 2000 года, причём наиболее значимой новой функцией является поддержка Unicode. Разработка, конечно, продолжалась и после мая, поэтому дерево 1.6 получило несколько исправлений для обеспечения прямой совместимости с Python 2.0. Поэтому 1.6 является частью эволюции Python, а не побочной ветвью.2122Стоит ли проявлять большой интерес к Python 1.6? Вероятно, нет. Релизы 1.6final и 2.0beta1 вышли в один день (5 сентября 2000 года), и планировалось завершить Python 2.0 примерно через месяц. Если у вас есть приложения, которые нужно поддерживать, то вряд ли есть смысл всё ломать переходом на 1.6, исправлять их, а затем снова ломать через месяц переходом на 2.0; лучше сразу перейти на 2.0. Большинство действительно интересных функций, описанных в этом документе, есть только в 2.0, потому что между маем и сентябрём было проделано много работы.2324## Новый процесс разработки2526Самое значительное изменение в Python 2.0 может быть вовсе не в коде, а в том, как разрабатывается Python: в мае 2000 года разработчики Python начали использовать инструменты, предоставленные SourceForge для хранения исходного кода, отслеживания сообщений об ошибках и управления очередью патчей. Чтобы сообщить об ошибке или отправить патч для Python 2.0, используйте средства отслеживания ошибок и управления патчами, доступные на странице проекта Python по адресу [http://sourceforge.net/projects/python/](https://python-all.ru/3.1/whatsnew/2.0.html).2728Самая важная из служб, теперь размещённых на SourceForge, – это дерево CVS Python, репозиторий с контролем версий, содержащий исходный код Python. Раньше доступ на запись к дереву CVS имели примерно 7 человек, и все патчи должен был просматривать и принимать один из участников этого короткого списка. Очевидно, это было не очень масштабируемо. Перенеся дерево CVS на SourceForge, стало возможным предоставить доступ на запись большему числу людей; по состоянию на сентябрь 2000 года 27 человек могли вносить изменения, что в четыре раза больше. Это делает возможными крупномасштабные изменения, которые не были бы предприняты, если бы их приходилось фильтровать через небольшую группу основных разработчиков. Например, однажды Петер Шнайдер-Камп решил отказаться от совместимости с K&R C и преобразовать исходный код C для Python в ANSI C. Получив одобрение в списке рассылки python-dev, он начал серию коммитов, которая длилась около недели, к нему присоединились другие разработчики, и работа была выполнена. Если бы доступ на запись был только у 5 человек, вероятно, эта задача была бы сочтена «хорошей, но не стоящей затрат времени и усилий» и никогда не была бы выполнена.2930Переход на использование служб SourceForge привёл к заметному увеличению скорости разработки. Теперь патчи отправляются, комментируются, дорабатываются людьми, отличными от первоначального отправителя, и пересылаются между людьми до тех пор, пока патч не будет признан достойным включения. Ошибки отслеживаются в одном центральном месте и могут быть назначены конкретному человеку для исправления, и мы можем подсчитывать количество открытых ошибок для измерения прогресса. Это не обошлось без затрат: теперь разработчикам приходится иметь дело с большим объёмом электронной почты, следить за большим количеством списков рассылки, и для новой среды пришлось написать специальные инструменты. Например, SourceForge отправляет стандартные уведомления о патчах и ошибках, которые совершенно бесполезны, поэтому Ка-Пинг Йи написал HTML-скрейпер, который отправляет более полезные сообщения.3132Лёгкость добавления кода вызвала некоторые первоначальные трудности роста, например, код принимался до того, как был готов, или без чёткого согласия группы разработчиков. Процесс утверждения, который возник, несколько похож на тот, что используется в группе Apache. Разработчики могут голосовать +1, +0, -0 или -1 за патч; +1 и -1 означают принятие или отклонение, тогда как +0 и -0 означают, что разработчику в основном безразлично это изменение, хотя с лёгким положительным или отрицательным оттенком. Наиболее существенное отличие от модели Apache заключается в том, что голосование носит в основном рекомендательный характер, позволяя Гвидо ван Россуму, имеющему статус Benevolent Dictator For Life (великодушный пожизненный диктатор), узнать общее мнение. Он всё ещё может игнорировать результаты голосования и одобрять или отклонять изменения, даже если сообщество с ним не согласно.3334Создание готового патча – последний шаг при добавлении новой возможности, и обычно он проще, чем предшествующая задача разработки хорошего дизайна. Обсуждения новых возможностей нередко раздуваются до длинных обсуждений в списках рассылки, из-за чего за обсуждением становится трудно следить; да и никто не может прочитать каждое сообщение в python-dev. Поэтому был создан относительно формальный процесс написания предложений по улучшению Python (PEP), построенный по образцу процесса RFC в Интернете. PEP – это черновые документы, описывающие предлагаемую новую возможность; они постоянно дорабатываются, пока сообщество не придет к консенсусу, принимая или отклоняя предложение. Цитируя введение к PEP 1, “PEP Purpose and Guidelines”:3536> PEP означает Python Enhancement Proposal (предложение по улучшению Python). PEP – это проектный документ, предоставляющий информацию сообществу Python или описывающий новую возможность для Python. PEP должен содержать краткую техническую спецификацию функции и обоснование этой функции.37>38> Мы предполагаем, что PEP будут основным механизмом предложения новых функций, сбора мнений сообщества по вопросу и документирования проектных решений, принятых в Python. Автор PEP отвечает за достижение консенсуса в сообществе и документирование разногласий.3940Остальную часть PEP 1 читайте для подробностей о редакторском процессе, стиле и формате PEP. PEP хранятся в дереве CVS Python на SourceForge, хотя они не являются частью дистрибутива Python 2.0, а также доступны в HTML-форме на [http://www.python.org/peps/](https://python-all.ru/3.1/whatsnew/2.0.html). По состоянию на сентябрь 2000 года существует 25 PEP – от PEP 201 «Lockstep Iteration» до PEP 225 «Elementwise/Objectwise Operators».4142## Юникод4344Самая большая новая функция в Python 2.0 – это новый фундаментальный тип данных: строки Unicode. В Unicode для представления символов используются 16-битные числа вместо 8-битных, используемых в ASCII, что означает поддержку 65 536 различных символов.4546Окончательный интерфейс поддержки Unicode был разработан в ходе бесчисленных, часто бурных обсуждений в списке рассылки python-dev и в основном реализован Марком-Андре Лембургом на основе реализации строкового типа Unicode Фредрика Лунда. Подробное описание интерфейса было оформлено как [**PEP 100**](https://python-all.ru/3.1/whatsnew/2.0.html), «Python Unicode Integration». В этой статье будут рассмотрены лишь наиболее важные моменты, касающиеся интерфейсов Unicode.4748В исходном коде Python строки Unicode записываются как `u"string"`. Произвольные символы Unicode можно записать с помощью новой управляющей последовательности `\uHHHH`, где *HHHH* – 4-значное шестнадцатеричное число от 0000 до FFFF. Существующая управляющая последовательность `\xHHHH` также может использоваться, а восьмеричные последовательности можно применять для символов до U+01FF, что обозначается `\777`.4950Unicode strings, just like regular strings, are an immutable sequence type. They can be indexed and sliced, but not modified in place. Unicode strings have an `encode( [encoding] )` method that returns an 8-bit string in the desired encoding. Encodings are named by strings, such as `'ascii'`, `'utf-8'`, `'iso-8859-1'`, or whatever. A codec API is defined for implementing and registering new encodings that are then available throughout a Python program. If an encoding isn’t specified, the default encoding is usually 7-bit ASCII, though it can be changed for your Python installation by calling the `sys.setdefaultencoding(encoding)()` function in a customised version of `site.py`.5152Объединение 8-битных и Unicode строк всегда приводит к Unicode с использованием кодировки ASCII по умолчанию; результатом `'a' + u'bc'` является `u'abc'`.5354Были добавлены новые встроенные функции, а существующие встроенные функции изменены для поддержки Unicode:5556- `unichr(ch)` возвращает строку Unicode длиной в 1 символ, содержащую символ *ch*.57- `ord(u)`, где *u* – это обычная или Unicode строка длиной в 1 символ, возвращает номер символа в виде целого числа.58- `unicode(string [, encoding] [, errors] )` создаёт строку Unicode из 8-битной строки. `encoding` – это строка, задающая используемую кодировку. Параметр `errors` определяет обработку символов, недопустимых для текущей кодировки; передача значения `'strict'` приводит к возникновению исключения при любой ошибке кодирования, тогда как `'ignore'` вызывает игнорирование ошибок, а `'replace'` использует U+FFFD, официальный заменяющий символ, в случае проблем.59- Инструкция `exec` и различные встроенные функции, такие как `eval()`, `getattr()` и `setattr()`, также будут принимать строки Unicode наравне с обычными строками. (Возможно, в процессе исправления были пропущены некоторые встроенные функции; если вы найдёте встроенную функцию, которая принимает строки, но совсем не принимает строки Unicode, сообщите об этом как об ошибке.)6061Новый модуль [`unicodedata`](https://python-all.ru/3.1/library/unicodedata.html#module-unicodedata) предоставляет интерфейс к свойствам символов Unicode. Например, `unicodedata.category(u'A')` возвращает строку из двух символов «Lu», где «L» означает букву, а «u» – что она в верхнем регистре. `unicodedata.bidirectional(u'\u0660')` возвращает «AN», что означает, что U+0660 является арабской цифрой.6263The [`codecs`](https://python-all.ru/3.1/library/codecs.html#module-codecs) module contains functions to look up existing encodings and register new ones. Unless you want to implement a new encoding, you’ll most often use the `codecs.lookup(encoding)()` function, which returns a 4-element tuple: `(encode_func, decode_func, stream_reader, stream_writer)`.6465- *encode\_func* – это функция, которая принимает строку Unicode и возвращает кортеж из двух элементов `(string, length)`. *string* – это 8-битная строка, содержащая часть (возможно, всю) строки Unicode, преобразованную в заданную кодировку, а *length* указывает, какая часть строки Unicode была преобразована.66- *decode\_func* – противоположность *encode\_func*; она принимает 8-битную строку и возвращает кортеж из двух элементов `(ustring, length)`, состоящий из результирующей строки Unicode *ustring* и целого числа *length*, указывающего, сколько 8-битной строки было обработано.67- *stream\_reader* – это класс, который поддерживает декодирование входных данных из потока. *stream\_reader(file\_obj)* возвращает объект, поддерживающий методы `read()`, `readline()` и `readlines()`. Все эти методы будут преобразовывать данные из заданной кодировки и возвращать строки Unicode.68- *stream\_writer*, аналогично, – это класс, поддерживающий кодирование выходных данных в поток. *stream\_writer(file\_obj)* возвращает объект, который поддерживает методы `write()` и `writelines()`. Эти методы ожидают строки Unicode и преобразуют их в заданную кодировку при выводе.6970Например, следующий код записывает строку Unicode в файл, кодируя её в UTF-8:7172```python73import codecs7475unistr = u'\u0660\u2000ab ...'7677(UTF8_encode, UTF8_decode,78 UTF8_streamreader, UTF8_streamwriter) = codecs.lookup('UTF-8')7980output = UTF8_streamwriter( open( '/tmp/output', 'wb') )81output.write( unistr )82output.close()83```8485Следующий код затем читает входные данные в UTF-8 из файла:8687```python88input = UTF8_streamreader( open( '/tmp/output', 'rb') )89print repr(input.read())90input.close()91```9293Регулярные выражения с поддержкой Unicode доступны через модуль [`re`](https://python-all.ru/3.1/library/re.html#module-re), который имеет новую базовую реализацию под названием SRE, написанную Фредриком Лундом из Secret Labs AB.9495Был добавлен параметр командной строки `-U`, который заставляет компилятор Python интерпретировать все строковые литералы как литералы строк Unicode. Это предназначено для использования при тестировании и подготовке вашего кода Python к будущим версиям, поскольку в какой-то будущей версии Python может быть прекращена поддержка 8-битных строк и останутся только строки Unicode.9697## Списочные включения9899Списки – это основной тип данных в Python, и многие программы так или иначе работают со списками. Две распространённые операции над списками – это перебор элементов с выбором тех, которые удовлетворяют определённому условию, или применение некоторой функции к каждому элементу. Например, имея список строк, можно захотеть извлечь все строки, содержащие заданную подстроку, или удалить завершающие пробелы в каждой строке.100101Существующие функции [`map()`](https://python-all.ru/3.1/library/functions.html#map) и [`filter()`](https://python-all.ru/3.1/library/functions.html#filter) могут использоваться для этой цели, но они требуют в качестве одного из аргументов функцию. Это нормально, если существует готовая встроенная функция, которую можно передать напрямую, но если её нет, приходится создавать небольшую функцию для выполнения требуемой работы, и правила областей видимости Python делают результат некрасивым, если маленькой функции нужна дополнительная информация. Возьмём первый пример из предыдущего абзаца: поиск всех строк в списке, содержащих заданную подстроку. Можно было бы написать следующее:102103```python104# По списку L создать список всех строк105# содержащих подстроку S.106sublist = filter( lambda s, substring=S:107 string.find(s, substring) != -1,108 L)109```110111Из-за правил области видимости Python используется аргумент по умолчанию, чтобы анонимная функция, созданная инструкцией [`lambda`](https://python-all.ru/3.1/reference/expressions.html#lambda), знала, какая подстрока ищется. Списковые включения делают это чище:112113```python114sublist = [ s for s in L if string.find(s, S) != -1 ]115```116117Списочные включения имеют следующий вид:118119```python120[ expression for expr in sequence1121 for expr2 in sequence2 ...122 for exprN in sequenceN123 if condition ]124```125126The [`for`](https://python-all.ru/3.1/reference/compound_stmts.html#for)...[`in`](https://python-all.ru/3.1/reference/expressions.html#in) clauses contain the sequences to be iterated over. The sequences do not have to be the same length, because they are *not* iterated over in parallel, but from left to right; this is explained more clearly in the following paragraphs. The elements of the generated list will be the successive values of *expression*. The final [`if`](https://python-all.ru/3.1/reference/compound_stmts.html#if) clause is optional; if present, *expression* is only evaluated and added to the result if *condition* is true.127128Чтобы прояснить семантику, списочное включение эквивалентно следующему коду Python:129130```python131for expr1 in sequence1:132 for expr2 in sequence2:133 ...134 for exprN in sequenceN:135 if (condition):136 # Добавить значение137 # выражения в138 # результирующий список.139```140141Это означает, что при наличии нескольких предложений [`for`](https://python-all.ru/3.1/reference/compound_stmts.html#for)...[`in`](https://python-all.ru/3.1/reference/expressions.html#in) результирующий список будет равен произведению длин всех последовательностей. Если у вас есть два списка длиной 3, выходной список будет содержать 9 элементов:142143```python144seq1 = 'abc'145seq2 = (1,2,3)146>>> [ (x,y) for x in seq1 for y in seq2]147[('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3), ('c', 1),148('c', 2), ('c', 3)]149```150151Чтобы избежать неоднозначности в грамматике Python, если *expression* создаёт кортеж, его необходимо окружить круглыми скобками. Первое списочное включение ниже содержит синтаксическую ошибку, тогда как второе – корректно:152153```python154# Синтаксическая ошибка155[ x,y for x in seq1 for y in seq2]156# Верно157[ (x,y) for x in seq1 for y in seq2]158```159160Идея списковых включений изначально пришла из функционального языка программирования Haskell ([http://www.haskell.org](https://python-all.ru/3.1/whatsnew/2.0.html)). Грег Юинг наиболее убедительно аргументировал их добавление в Python и написал первоначальный патч для списковых включений, который затем обсуждался, казалось, бесконечно долго в списке рассылки python-dev и поддерживался в актуальном состоянии Скипом Монтанаро.161162## Составное присваивание163164Составные операторы присваивания, ещё одна давно запрашиваемая возможность, были добавлены в Python 2.0. Составные операторы присваивания включают `+=`, `-=`, `*=` и так далее. Например, инструкция `a += 2` увеличивает значение переменной `a` на 2, что эквивалентно чуть более длинной записи `a = a + 2`.165166Полный список поддерживаемых операторов присваивания: `+=`, `-=`, `*=`, `/=`, `%=`, `**=`, `&=`, `|=`, `^=`, `>>=` и `<<=`. Классы Python могут переопределять составные операторы присваивания, определяя методы с именами [`__iadd__()`](https://python-all.ru/3.1/reference/datamodel.html#object.__iadd__), [`__isub__()`](https://python-all.ru/3.1/reference/datamodel.html#object.__isub__) и т.д. Например, следующий класс `Number` хранит число и поддерживает использование += для создания нового экземпляра с увеличенным значением.167168```python169class Number:170 def __init__(self, value):171 self.value = value172 def __iadd__(self, increment):173 return Number( self.value + increment)174175n = Number(5)176n += 3177print n.value178```179180Специальный метод [`__iadd__()`](https://python-all.ru/3.1/reference/datamodel.html#object.__iadd__) вызывается со значением приращения и должен возвращать новый экземпляр с соответствующим изменённым значением; это возвращаемое значение связывается как новое значение переменной в левой части.181182Операторы составного присваивания были впервые введены в языке программирования C, и большинство языков, производных от C, такие как **awk**, C++, Java, Perl и PHP, также их поддерживают. Патч для составного присваивания был реализован Томасом Ваутерсом.183184## Методы строк185186До сих пор функциональность для работы со строками находилась в модуле [`string`](https://python-all.ru/3.1/library/string.html#module-string), который обычно был внешним интерфейсом для написанного на C модуля `strop`. Добавление Unicode создало трудность для модуля `strop`, потому что все функции нужно было бы переписать, чтобы они принимали как 8-битные, так и Unicode строки. Для таких функций, как `string.replace()`, которая принимает 3 строковых аргумента, это означает восемь возможных перестановок и, соответственно, сложный код.187188Вместо этого Python 2.0 перекладывает проблему на строковый тип, делая функциональность для работы со строками доступной через методы как для 8-битных строк, так и для строк Unicode.189190```python191>>> 'andrew'.capitalize()192'Andrew'193>>> 'hostname'.replace('os', 'linux')194'hlinuxtname'195>>> 'moshe'.find('sh')1962197```198199Одна вещь, которая не изменилась, несмотря на известную первоапрельскую шутку, – это то, что строки Python неизменяемы. Таким образом, строковые методы возвращают новые строки и не изменяют строку, к которой они применяются.200201Старый модуль [`string`](https://python-all.ru/3.1/library/string.html#module-string) всё ещё существует для обратной совместимости, но в основном он выступает в качестве внешнего интерфейса к новым строковым методам.202203Два метода, не имеющие аналогов в версиях до 2.0 (хотя они существовали в JPython уже довольно давно): `startswith()` и `endswith()`. `s.startswith(t)` эквивалентно `s[:len(t)] == t`, а `s.endswith(t)` эквивалентно `s[-len(t):] == t`.204205Ещё один метод, заслуживающий особого упоминания, – это `join()`. Метод `join()` строки принимает один параметр – последовательность строк – и эквивалентен функции `string.join()` из старого модуля [`string`](https://python-all.ru/3.1/library/string.html#module-string), но с обратным порядком аргументов. Другими словами, `s.join(seq)` эквивалентно старой записи `string.join(seq, s)`.206207## Сборка мусора циклических ссылок208209Реализация Python на C использует подсчёт ссылок для реализации сборки мусора. Каждый объект Python хранит счётчик количества ссылок, указывающих на него, и обновляет этот счётчик при создании или удалении ссылок. Когда счётчик ссылок достигает нуля, объект становится недоступным, поскольку для доступа к объекту необходима ссылка на него, а если счётчик равен нулю, ссылок больше не существует.210211Подсчёт ссылок имеет ряд приятных свойств: его легко понять и реализовать, а результирующая реализация является переносимой, достаточно быстрой и хорошо взаимодействует с другими библиотеками, реализующими собственные схемы управления памятью. Основная проблема подсчёта ссылок заключается в том, что он иногда не замечает, что объекты стали недоступными, что приводит к утечке памяти. Это происходит при наличии циклических ссылок.212213Рассмотрим простейший возможный цикл – экземпляр класса, который содержит ссылку на самого себя:214215```python216instance = SomeClass()217instance.myself = instance218```219220После выполнения двух указанных выше строк кода счетчик ссылок на `instance` равен 2; одна ссылка – от переменной с именем `'instance'`, а другая – от атрибута `myself` экземпляра.221222Если следующей строкой кода будет `del instance`, что произойдет? Счетчик ссылок `instance` уменьшится на 1, так что он станет равен 1; ссылка в атрибуте `myself` все еще существует. Однако экземпляр больше недоступен через код Python и может быть удален. Несколько объектов могут образовывать цикл, если они ссылаются друг на друга, что приводит к утечке всех объектов.223224Python 2.0 исправляет эту проблему, периодически выполняя алгоритм обнаружения циклов, который ищет недоступные циклы и удаляет задействованные объекты. Новый модуль [`gc`](https://python-all.ru/3.1/library/gc.html#module-gc) предоставляет функции для сборки мусора, получения отладочной статистики и настройки параметров сборщика.225226Выполнение алгоритма обнаружения циклов требует некоторого времени, поэтому приводит к дополнительным накладным расходам. Предполагается, что после получения опыта работы со сборкой циклов в Python 2.0, Python 2.1 сможет минимизировать накладные расходы за счет тщательной настройки. Пока не очевидно, насколько падает производительность, потому что бенчмаркинг этой задачи сложен и сильно зависит от того, как часто программа создает и уничтожает объекты. Обнаружение циклов можно отключить при компиляции Python, если вы не можете позволить себе даже малейшего снижения скорости или подозреваете, что сборка циклов ошибочна, указав флаг *--without-cycle-gc* при запуске сценария **configure**.227228Несколько человек взялись за эту проблему и внесли свой вклад в решение. Ранняя реализация подхода с обнаружением циклов была написана Тоби Келси. Текущий алгоритм предложил Эрик Тидерманн во время визита в CNRI, а Гвидо ван Россум и Нил Шеменауэр написали две разные реализации, которые позже были объединены Нилом. Многие другие люди высказывали предложения по ходу дела; в архивах марта 2000 года списка рассылки python-dev содержится большая часть соответствующих обсуждений, особенно в темах «Reference cycle collection for Python» и «Finalization again».229230## Другие основные изменения231232В синтаксис и встроенные функции Python был внесён ряд небольших изменений. Ни одно из них не является очень масштабным, но все они представляют собой удобные возможности.233234### Небольшие изменения языка235236Новый синтаксис упрощает вызов функции с кортежем аргументов и/или словарем именованных аргументов. В Python 1.5 и ранее для этого использовалась встроенная функция `apply()`: `apply(f, args, kw)` вызывает функцию `f()` с кортежем аргументов *args* и именованными аргументами из словаря *kw*. `apply()` осталась и в 2.0, но благодаря патчу от Грега Юинга `f(*args, **kw)` стал более коротким и понятным способом достичь того же эффекта. Этот синтаксис симметричен синтаксису определения функций:237238```python239def f(*args, **kw):240 # args – это кортеж позиционных аргументов,241 # kw – это словарь именованных аргументов242 ...243```244245The `print` statement can now have its output directed to a file-like object by following the `print` with `>> file`, similar to the redirection operator in Unix shells. Previously you’d either have to use the `write()` method of the file-like object, which lacks the convenience and simplicity of `print`, or you could assign a new value to `sys.stdout` and then restore the old value. For sending output to standard error, it’s much easier to write this:246247```python248print >> sys.stderr, "Warning: action field not supplied"249```250251Модули теперь можно переименовывать при импорте, используя синтаксис `import module as name` или `from module import name as othername`. Патч был представлен Томасом Ваутерсом.252253Новый стиль форматирования доступен при использовании оператора `%`; ‘%r’ вставляет [`repr()`](https://python-all.ru/3.1/library/functions.html#repr) своего аргумента. Это было добавлено из соображений симметрии, на этот раз с существующим стилем ‘%s’, который вставляет [`str()`](https://python-all.ru/3.1/library/functions.html#str) своего аргумента. Например, `'%r %s' % ('abc', 'abc')` возвращает строку, содержащую `'abc' abc`.254255Раньше не было возможности реализовать класс, переопределяющий встроенный оператор [`in`](https://python-all.ru/3.1/reference/expressions.html#in) Python и реализующий собственную версию. `obj in seq` возвращает true, если *obj* присутствует в последовательности *seq*; Python вычисляет это, просто перебирая все индексы последовательности, пока не будет найден *obj* или не возникнет [`IndexError`](https://python-all.ru/3.1/library/exceptions.html#IndexError). Моше Задка представил патч, добавляющий магический метод [`__contains__()`](https://python-all.ru/3.1/reference/datamodel.html#object.__contains__) для предоставления собственной реализации оператора [`in`](https://python-all.ru/3.1/reference/expressions.html#in). Кроме того, новые встроенные объекты, написанные на C, могут определять, что для них означает [`in`](https://python-all.ru/3.1/reference/expressions.html#in), через новый слот в протоколе последовательностей.256257Более ранние версии Python использовали рекурсивный алгоритм для удаления объектов. Глубоко вложенные структуры данных могли привести к переполнению C-стека интерпретатора и аварийному завершению; Кристиан Тисмер переписал логику удаления, чтобы исправить эту проблему. Похожим образом, сравнение рекурсивных объектов приводило к бесконечной рекурсии и краху; Джереми Хилтон переписал код так, чтобы он больше не падал, а выдавал полезный результат. Например, после этого кода:258259```python260a = []261b = []262a.append(a)263b.append(b)264```265266Сравнение `a==b` возвращает true, потому что две рекурсивные структуры данных изоморфны. См. обсуждение в теме «trashcan and PR#7» в архивах апреля 2000 года списка рассылки python-dev, где велась дискуссия, приведшая к этой реализации, а также полезные ссылки. Обратите внимание: теперь сравнения также могут вызывать исключения. В более ранних версиях Python операция сравнения, например `cmp(a,b)`, всегда давала ответ, даже если пользовательский метод `__cmp__()` сталкивался с ошибкой, так как возникшее исключение просто молча проглатывалось.267268Проведена работа по портированию Python на 64-разрядную Windows на процессоре Itanium, в основном Трентом Миком из ActiveState. (Как ни странно, `sys.platform` по-прежнему `'win32'` на Win64, поскольку, похоже, для упрощения портирования MS Visual C++ обрабатывает код как 32-разрядный на Itanium.) PythonWin также поддерживает Windows CE; дополнительную информацию см. на странице Python CE по адресу [http://pythonce.sourceforge.net/](https://python-all.ru/3.1/whatsnew/2.0.html).269270Ещё одна новая платформа – Darwin/MacOS X; начальная поддержка для неё появилась в Python 2.0. Динамическая загрузка работает, если указать «configure –with-dyld –with-suffix=.x». За дополнительными инструкциями обращайтесь к файлу README в дистрибутиве исходного кода Python.271272Была предпринята попытка смягчить один из недостатков Python – часто сбивающее с толку исключение [`NameError`](https://python-all.ru/3.1/library/exceptions.html#NameError), когда код обращается к локальной переменной до того, как ей присвоено значение. Например, следующий код вызывает исключение на операторе `print` как в 1.5.2, так и в 2.0; в 1.5.2 возбуждается исключение [`NameError`](https://python-all.ru/3.1/library/exceptions.html#NameError), а в 2.0 – новое исключение [`UnboundLocalError`](https://python-all.ru/3.1/library/exceptions.html#UnboundLocalError). [`UnboundLocalError`](https://python-all.ru/3.1/library/exceptions.html#UnboundLocalError) является подклассом [`NameError`](https://python-all.ru/3.1/library/exceptions.html#NameError), поэтому любой существующий код, ожидающий возбуждения [`NameError`](https://python-all.ru/3.1/library/exceptions.html#NameError), по-прежнему должен работать.273274```python275def f():276 print "i=",i277 i = i + 1278f()279```280281Введены два новых исключения: [`TabError`](https://python-all.ru/3.1/library/exceptions.html#TabError) и [`IndentationError`](https://python-all.ru/3.1/library/exceptions.html#IndentationError). Оба являются подклассами [`SyntaxError`](https://python-all.ru/3.1/library/exceptions.html#SyntaxError) и возбуждаются, когда код Python имеет неправильные отступы.282283### Изменения во встроенных функциях284285Добавлена новая встроенная функция `zip(seq1, seq2, ...)()`. [`zip()`](https://python-all.ru/3.1/library/functions.html#zip) возвращает список кортежей, где каждый кортеж содержит i-й элемент из каждой последовательности-аргумента. Разница между [`zip()`](https://python-all.ru/3.1/library/functions.html#zip) и `map(None, seq1, seq2)` в том, что [`map()`](https://python-all.ru/3.1/library/functions.html#map) дополняет последовательности значением `None`, если они не одинаковой длины, а [`zip()`](https://python-all.ru/3.1/library/functions.html#zip) укорачивает возвращаемый список до длины самой короткой последовательности.286287Функции [`int()`](https://python-all.ru/3.1/library/functions.html#int) и `long()` теперь принимают необязательный параметр «base», если первый аргумент является строкой. `int('123', 10)` возвращает 123, а `int('123', 16)` возвращает 291. `int(123, 16)` возбуждает исключение [`TypeError`](https://python-all.ru/3.1/library/exceptions.html#TypeError) с сообщением «can't convert non-string with explicit base».288289В модуль [`sys`](https://python-all.ru/3.1/library/sys.html#module-sys) добавлена новая переменная, содержащая более подробную информацию о версии. `sys.version_info` – это кортеж `(major, minor, micro, level, serial)`. Например, в гипотетической версии 2.0.1beta1 значение `sys.version_info` было бы `(2, 0, 1, 'beta', 1)`. *level* – это строка, например `"alpha"`, `"beta"` или `"final"` для окончательного релиза.290291У словарей появился новый необычный метод `setdefault(key, default)()`, который ведёт себя похоже на существующий метод `get()`. Однако, если ключ отсутствует, `setdefault()` не только возвращает значение *default*, как это сделал бы `get()`, но и вставляет его в словарь как значение для ключа *key*. Таким образом, следующие строки кода:292293```python294if dict.has_key( key ): return dict[key]295else:296 dict[key] = []297 return dict[key]298```299300могут быть заменены одним оператором `return dict.setdefault(key, [])`.301302Интерпретатор устанавливает максимальную глубину рекурсии, чтобы перехватить неконтролируемую рекурсию до того, как будет заполнен стек C и произойдет дамп ядра или GPF. Ранее этот предел был фиксирован при компиляции Python, но в 2.0 максимальную глубину рекурсии можно читать и изменять с помощью [`sys.getrecursionlimit()`](https://python-all.ru/3.1/library/sys.html#sys.getrecursionlimit) и [`sys.setrecursionlimit()`](https://python-all.ru/3.1/library/sys.html#sys.setrecursionlimit). Значение по умолчанию – 1000, а приблизительное максимальное значение для данной платформы можно узнать, запустив новый скрипт `Misc/find_recursionlimit.py`.303304## Переход на версию 2.0305306Новые релизы Python стараются быть совместимыми с предыдущими, и до сих пор это удавалось довольно хорошо. Однако некоторые изменения считаются достаточно полезными, обычно потому что они исправляют изначальные проектные решения, оказавшиеся ошибочными, и нарушения обратной совместимости не всегда можно избежать. В этом разделе перечислены изменения в Python 2.0, которые могут привести к неработоспособности старого кода.307308Изменение, которое, вероятно, сломает больше всего кода, – это ужесточение требований к аргументам, принимаемым некоторыми методами. Некоторые методы раньше принимали несколько аргументов и рассматривали их как кортеж, в частности различные методы списков, такие как `append()` и `insert()`. В более ранних версиях Python, если `L` – список, то `L.append( 1,2 )` добавляет кортеж `(1,2)` в список. В Python 2.0 это вызывает исключение [`TypeError`](https://python-all.ru/3.1/library/exceptions.html#TypeError) с сообщением: «append requires exactly 1 argument; 2 given». Исправление состоит в том, чтобы просто добавить дополнительные скобки и передать оба значения как кортеж: `L.append( (1,2) )`.309310Более ранние версии этих методов были более снисходительными, поскольку они использовали старую функцию в C-интерфейсе Python для разбора своих аргументов; версия 2.0 модернизирует их, чтобы использовать [`PyArg_ParseTuple()`](https://python-all.ru/3.1/c-api/arg.html#PyArg_ParseTuple) – текущую функцию разбора аргументов, которая выдает более полезные сообщения об ошибках и считает вызовы с несколькими аргументами ошибками. Если вам абсолютно необходимо использовать 2.0, но вы не можете исправить свой код, вы можете отредактировать `Objects/listobject.c` и определить символ препроцессора `NO_STRICT_LIST_APPEND`, чтобы сохранить старое поведение; это не рекомендуется.311312Некоторые функции в модуле [`socket`](https://python-all.ru/3.1/library/socket.html#module-socket) по-прежнему снисходительны в этом отношении. Например, `socket.connect( ('hostname', 25) )()` – правильная форма, передающая кортеж, представляющий IP-адрес, но `socket.connect( 'hostname', 25 )()` также работает. `socket.connect_ex()` и `socket.bind()` столь же снисходительны. В версии 2.0alpha1 эти функции были ужесточены, но поскольку в документации фактически использовалась ошибочная форма с несколькими аргументами, многие люди написали код, который бы сломался при более строгой проверке. GvR откатил изменения под давлением общественности, поэтому для модуля [`socket`](https://python-all.ru/3.1/library/socket.html#module-socket) документация была исправлена, а форма с несколькими аргументами просто помечена как устаревшая; в будущей версии Python она *будет* снова ужесточена.313314Управляющая последовательность `\x` в строковых литералах теперь принимает ровно 2 шестнадцатеричные цифры. Раньше она потребляла все шестнадцатеричные цифры после 'x' и брала младшие 8 бит результата, так что `\x123456` было эквивалентно `\x56`.315316Исключения [`AttributeError`](https://python-all.ru/3.1/library/exceptions.html#AttributeError) и [`NameError`](https://python-all.ru/3.1/library/exceptions.html#NameError) теперь имеют более дружественные сообщения об ошибках, текст которых будет выглядеть примерно так: `'Spam' instance has no attribute 'eggs'` или `name 'eggs' is not defined`. Раньше сообщение об ошибке было просто именем отсутствующего атрибута `eggs`, и код, написанный с учетом этого, сломается в 2.0.317318Проделана определенная работа, чтобы сделать обычные целые числа и длинные целые числа более взаимозаменяемыми. В версии 1.5.2 для Solaris была добавлена поддержка больших файлов, позволяющая читать файлы размером более 2 ГБ; это привело к тому, что метод `tell()` файловых объектов стал возвращать длинное целое вместо обычного. Некоторый код вычитал два смещения файла и пытался использовать результат для умножения последовательности или среза строки, но это вызывало исключение [`TypeError`](https://python-all.ru/3.1/library/exceptions.html#TypeError). В версии 2.0 длинные целые можно использовать для умножения или среза последовательности, и это будет работать интуитивно ожидаемым образом; `3L * 'abc'` дает 'abcabcabc', а `(0,1,2,3)[2L:4L]` дает (2,3). Длинные целые также можно использовать в различных контекстах, где раньше принимались только целые числа, например в методе `seek()` файловых объектов и в форматах, поддерживаемых оператором `%` (`%d`, `%i`, `%x` и т.д.). Например, `"%d" % 2L**64` выдаст строку `18446744073709551616`.319320Самое тонкое изменение, касающееся длинных целых, заключается в том, что результат [`str()`](https://python-all.ru/3.1/library/functions.html#str) от длинного целого больше не содержит завершающего символа 'L', хотя [`repr()`](https://python-all.ru/3.1/library/functions.html#repr) все еще включает его. 'L' раздражал многих людей, которые хотели печатать длинные целые, выглядевшие как обычные целые, так как им приходилось делать лишние действия, чтобы отрезать этот символ. В версии 2.0 это больше не проблема, но код, который делает `str(longval)[:-1]` и предполагает, что 'L' присутствует, теперь потеряет последнюю цифру.321322Вычисление [`repr()`](https://python-all.ru/3.1/library/functions.html#repr) от числа с плавающей запятой теперь использует другую точность форматирования, чем [`str()`](https://python-all.ru/3.1/library/functions.html#str). [`repr()`](https://python-all.ru/3.1/library/functions.html#repr) использует строку формата `%.17g` для C-функции `sprintf()`, в то время как [`str()`](https://python-all.ru/3.1/library/functions.html#str) использует `%.12g`, как и раньше. Результат в том, что [`repr()`](https://python-all.ru/3.1/library/functions.html#repr) иногда может показывать больше десятичных знаков, чем [`str()`](https://python-all.ru/3.1/library/functions.html#str), для некоторых чисел. Например, число 8.1 не может быть точно представлено в двоичном виде, поэтому `repr(8.1)` равно `'8.0999999999999996'`, а str(8.1) равно `'8.1'`.323324Параметр командной строки `-X`, который превращал все стандартные исключения в строки вместо классов, был удален; теперь стандартные исключения всегда будут классами. Модуль `exceptions`, содержащий стандартные исключения, был переведен с Python на встроенный C-модуль, написанный Барри Уорсо и Фредриком Лундом.325326## Изменения в расширении и встраивании327328Некоторые изменения находятся «под капотом» и будут заметны только тем, кто пишет модули расширения на C или встраивает интерпретатор Python в более крупное приложение. Если вы не работаете с C API Python, можете смело пропустить этот раздел.329330Номер версии Python C API был увеличен, поэтому расширения на C, скомпилированные для версии 1.5.2, должны быть перекомпилированы для работы с версией 2.0. В Windows из-за особенностей работы DLL Python 2.0 не может импортировать сторонние расширения, собранные для Python 1.5.x; Python вызовет исключение, и импорт не удастся.331332Пользователи модуля ExtensionClass Джима Фултона будут рады узнать, что были добавлены перехватчики, благодаря которым ExtensionClasses теперь поддерживаются функциями [`isinstance()`](https://python-all.ru/3.1/library/functions.html#isinstance) и [`issubclass()`](https://python-all.ru/3.1/library/functions.html#issubclass). Это означает, что больше не нужно помнить о необходимости писать код вроде `if type(obj) == myExtensionClass`, а можно использовать более естественный `if isinstance(obj, myExtensionClass)`.333334The `Python/importdl.c` file, which was a mass of #ifdefs to support dynamic loading on many different platforms, was cleaned up and reorganised by Greg Stein. `importdl.c` is now quite small, and platform-specific code has been moved into a bunch of `Python/dynload_*.c` files. Another cleanup: there were also a number of `my*.h` files in the Include/ directory that held various portability hacks; they’ve been merged into a single file, `Include/pyport.h`.335336Долгожданная реструктуризация malloc, выполненная Владимиром Марангозовым, была завершена, чтобы интерпретатор Python мог легко использовать собственный аллокатор вместо стандартного `malloc()` из C. Документацию см. в комментариях в `Include/pymem.h` и `Include/objimpl.h`. За подробными обсуждениями, в ходе которых вырабатывался интерфейс, обращайтесь к веб-архивам списков «patches» и «python-dev» на python.org.337338Последние версии среды разработки GUSI для MacOS поддерживают потоки POSIX. Поэтому поддержка потоков POSIX в Python теперь работает на Macintosh. Также была добавлена поддержка потоков с использованием пользовательской библиотеки GNU `pth`.339340Поддержка потоков в Windows также была улучшена. Windows поддерживает блокировки потоков, которые используют объекты ядра только в случае конкуренции; в типичном случае, когда конкуренции нет, используются более простые функции, которые на порядок быстрее. Потоковая версия Python 1.5.2 на NT работает в два раза медленнее однопоточной; с изменениями в 2.0 разница составляет всего 10%. Эти улучшения были внесены Яковом Марковичем.341342Исходный код Python 2.0 теперь использует только прототипы ANSI C, поэтому для компиляции Python требуется компилятор ANSI C, и больше нельзя использовать компилятор, поддерживающий только K&R C.343344Ранее виртуальная машина Python использовала 16-битные числа в своём байт-коде, что ограничивало размер исходных файлов. В частности, это влияло на максимальный размер литеральных списков и словарей в исходном коде Python; время от времени разработчики, генерирующие код Python, сталкивались с этим ограничением. Патч Чарльза Дж. Уолдмана поднимает предел с `2^16` до `2^{32}`.345346Было добавлено три новые удобные функции, предназначенные для добавления констант в словарь модуля при его инициализации: [`PyModule_AddObject()`](https://python-all.ru/3.1/c-api/module.html#PyModule_AddObject), [`PyModule_AddIntConstant()`](https://python-all.ru/3.1/c-api/module.html#PyModule_AddIntConstant) и [`PyModule_AddStringConstant()`](https://python-all.ru/3.1/c-api/module.html#PyModule_AddStringConstant). Каждая из этих функций принимает объект модуля, C-строку, завершающуюся нулевым символом, содержащую имя, которое нужно добавить, и третий аргумент – значение, присваиваемое этому имени. Этот третий аргумент – соответственно, объект Python, C-long или C-строка.347348Добавлен API-обёртка для обработчиков сигналов в стиле Unix. [`PyOS_getsig()`](https://python-all.ru/3.1/c-api/sys.html#PyOS_getsig) получает обработчик сигнала, а [`PyOS_setsig()`](https://python-all.ru/3.1/c-api/sys.html#PyOS_setsig) устанавливает новый обработчик.349350## Distutils: упрощение установки модулей351352До Python 2.0 установка модулей была утомительным делом – не было возможности автоматически определить, где установлен Python, или какие параметры компилятора использовать для модулей расширения. Авторам программного обеспечения приходилось проходить через утомительный ритуал редактирования файлов Makefile и конфигурационных файлов, который нормально работал только на Unix и не поддерживал Windows и MacOS. Пользователи Python сталкивались с сильно различающимися инструкциями по установке для разных пакетов расширений, что делало администрирование установки Python довольно обременительным.353354Специальная группа по дистрибутивам (SIG), руководимая Грегом Уордом, создала Distutils – систему, значительно упрощающую установку пакетов. Они образуют пакет [`distutils`](https://python-all.ru/3.1/library/distutils.html#module-distutils), новую часть стандартной библиотеки Python. В лучшем случае установка модуля Python из исходников потребует следующих шагов: сначала нужно распаковать tarball или zip-архив, а затем выполнить “`python setup.py install`”. Платформа будет определена автоматически, компилятор распознан, модули-расширения на C скомпилированы, а дистрибутив установлен в нужную директорию. Дополнительные аргументы командной строки дают больше контроля над процессом установки; пакет distutils предоставляет множество возможностей для переопределения настроек по умолчанию – разделение сборки и установки, сборка или установка в нестандартные директории и многое другое.355356Чтобы использовать Distutils, необходимо написать скрипт `setup.py`. В простейшем случае, когда программа содержит только .py-файлы, минимальный `setup.py` может состоять всего из нескольких строк:357358```python359from distutils.core import setup360setup (name = "foo", version = "1.0",361 py_modules = ["module1", "module2"])362```363364Файл `setup.py` ненамного сложнее, если программа состоит из нескольких пакетов:365366```python367from distutils.core import setup368setup (name = "foo", version = "1.0",369 packages = ["package", "package.subpackage"])370```371372Расширение на C может быть самым сложным случаем; вот пример, взятый из пакета PyXML:373374```python375from distutils.core import setup, Extension376377expat_extension = Extension('xml.parsers.pyexpat',378 define_macros = [('XML_NS', None)],379 include_dirs = [ 'extensions/expat/xmltok',380 'extensions/expat/xmlparse' ],381 sources = [ 'extensions/pyexpat.c',382 'extensions/expat/xmltok/xmltok.c',383 'extensions/expat/xmltok/xmlrole.c', ]384 )385setup (name = "PyXML", version = "0.5.4",386 ext_modules =[ expat_extension ] )387```388389Distutils также может создавать исходные и бинарные дистрибутивы. Команда «sdist», запускаемая как «`python setup.py sdist`», собирает исходный дистрибутив, например `foo-1.0.tar.gz`. Добавлять новые команды несложно; команды «bdist\_rpm» и «bdist\_wininst» уже были предоставлены для создания RPM-дистрибутива и установщика для Windows соответственно. Команды для создания других форматов дистрибутивов, таких как пакеты Debian и файлы Solaris `.pkg`, находятся на разных стадиях разработки.390391Всё это описано в новом руководстве *Distributing Python Modules*, которое пополняет основной набор документации Python.392393## Модули XML394395Python 1.5.2 включал простой XML-парсер в виде модуля `xmllib`, предоставленного Сьордом Мюллендером. С момента выпуска 1.5.2 стали распространены два различных интерфейса для обработки XML: SAX2 (версия 2 Simple API for XML) предоставляет событийно-ориентированный интерфейс с некоторым сходством с `xmllib`, а DOM (Document Object Model) предоставляет древовидный интерфейс, преобразующий XML-документ в дерево узлов, которое можно обойти и изменить. Python 2.0 включает интерфейс SAX2 и упрощённый интерфейс DOM в составе пакета `xml`. Здесь мы дадим краткий обзор этих новых интерфейсов; за полными подробностями обращайтесь к документации Python или исходному коду. Специальная группа Python по XML также работает над улучшенной документацией.396397### Поддержка SAX2398399SAX определяет событийно-ориентированный интерфейс для разбора XML. Чтобы использовать SAX, необходимо написать класс-обработчик SAX. Классы-обработчики наследуются от различных классов, предоставляемых SAX, и переопределяют различные методы, которые затем вызываются XML-парсером. Например, методы `startElement()` и `endElement()` вызываются для каждого открывающего и закрывающего тега, встреченных парсером, метод `characters()` вызывается для каждого фрагмента символьных данных и так далее.400401Преимущество событийно-ориентированного подхода в том, что весь документ не должен постоянно находиться в памяти, что важно при обработке действительно огромных документов. Однако написание класса-обработчика SAX может сильно усложниться, если вы пытаетесь модифицировать структуру документа каким-либо сложным образом.402403Например, эта небольшая программа определяет обработчик, который выводит сообщение для каждого открывающего и закрывающего тега, а затем разбирает файл `hamlet.xml` с его помощью:404405```python406from xml import sax407408class SimpleHandler(sax.ContentHandler):409 def startElement(self, name, attrs):410 print 'Start of element:', name, attrs.keys()411412 def endElement(self, name):413 print 'End of element:', name414415# Создать объект парсера416parser = sax.make_parser()417418# Указать ему, какой обработчик использовать419handler = SimpleHandler()420parser.setContentHandler( handler )421422# Разобрать файл!423parser.parse( 'hamlet.xml' )424```425426За дополнительной информацией обращайтесь к документации Python или XML HOWTO по адресу [http://pyxml.sourceforge.net/topics/howto/xml-howto.html](https://python-all.ru/3.1/whatsnew/2.0.html).427428### Поддержка DOM429430Document Object Model – это древовидное представление XML-документа. Экземпляр верхнего уровня `Document` является корнем дерева и имеет единственный дочерний элемент – экземпляр `Element` верхнего уровня. Этот `Element` имеет дочерние узлы, представляющие символьные данные и любые подэлементы, которые, в свою очередь, могут иметь собственные дочерние узлы и так далее. Используя DOM, можно обходить полученное дерево любым способом, получать значения элементов и атрибутов, вставлять и удалять узлы, а также преобразовывать дерево обратно в XML.431432DOM полезен для изменения XML-документов, поскольку можно создать DOM-дерево, изменить его, добавляя новые узлы или перестраивая поддеревья, а затем получить новый XML-документ на выходе. Также можно вручную построить DOM-дерево и преобразовать его в XML, что может быть более гибким способом создания XML-вывода, чем простая запись `<tag1>`...`</tag1>` в файл.433434Реализация DOM, входящая в состав Python, находится в модуле [`xml.dom.minidom`](https://python-all.ru/3.1/library/xml.dom.minidom.html#module-xml.dom.minidom). Это облегченная реализация DOM уровня 1 с поддержкой пространств имен XML. Для генерации DOM-дерева предоставляются вспомогательные функции `parse()` и `parseString()`:435436```python437from xml.dom import minidom438doc = minidom.parse('hamlet.xml')439```440441`doc` – это экземпляр `Document`. `Document`, как и все остальные классы DOM, такие как `Element` и `Text`, является подклассом базового класса `Node`. Поэтому все узлы DOM-дерева поддерживают определенные общие методы, например `toxml()`, который возвращает строку, содержащую XML-представление узла и его дочерних элементов. Каждый класс также имеет свои собственные специальные методы; например, экземпляры `Element` и `Document` имеют метод для поиска всех дочерних элементов с заданным именем тега. Продолжая предыдущий пример из двух строк:442443```python444perslist = doc.getElementsByTagName( 'PERSONA' )445print perslist[0].toxml()446print perslist[1].toxml()447```448449Для XML-файла *Hamlet* несколько строк выше выводят:450451```python452<PERSONA>CLAUDIUS, king of Denmark. </PERSONA>453<PERSONA>HAMLET, son to the late, and nephew to the present king.</PERSONA>454```455456Корневой элемент документа доступен как `doc.documentElement`, а его дочерние элементы можно легко изменять, удаляя, добавляя или убирая узлы:457458```python459root = doc.documentElement460461# Удалить первый дочерний элемент462root.removeChild( root.childNodes[0] )463464# Переместить новый первый дочерний элемент в конец465root.appendChild( root.childNodes[0] )466467# Вставить новый первый дочерний элемент (изначально468# третий дочерний элемент) перед 20-м дочерним элементом.469root.insertBefore( root.childNodes[0], root.childNodes[20] )470```471472Опять же, обратитесь к документации Python для получения полного списка различных классов `Node` и их разнообразных методов.473474### Отношение к PyXML475476Специальная группа по XML уже некоторое время работает над XML-кодом для Python. Её дистрибутив кода, называемый PyXML, доступен на веб-страницах группы по адресу [http://www.python.org/sigs/xml-sig/](https://python-all.ru/3.1/whatsnew/2.0.html). Дистрибутив PyXML также использовал имя пакета `xml`. Если вы писали программы, использующие PyXML, вы, вероятно, задаётесь вопросом о его совместимости с пакетом `xml` из версии 2.0.477478Ответ таков: пакет `xml` в Python 2.0 несовместим с PyXML, но может быть совместимым, если установить последнюю версию PyXML. Многие приложения могут обойтись поддержкой XML, входящей в Python 2.0, но более сложные приложения потребуют установки полного пакета PyXML. При установке версии PyXML 0.6.0 или новее заменяют пакет `xml`, поставляемый с Python, и являются строгим надмножеством стандартного пакета, добавляя множество дополнительных возможностей. Некоторые из дополнительных функций PyXML включают:479480- 4DOM – полная реализация DOM от FourThought, Inc.481- Валидирующий парсер xmlproc, написанный Ларсом Мариусом Гаршолем.482- Модуль-ускоритель парсера `sgmlop`, написанный Фредриком Лундом.483484## Изменения в модулях485486В обширную стандартную библиотеку Python было внесено множество улучшений и исправлений; некоторые из затронутых модулей включают [`readline`](https://python-all.ru/3.1/library/readline.html#module-readline), `ConfigParser`, [`cgi`](https://python-all.ru/3.1/library/cgi.html#module-cgi), [`calendar`](https://python-all.ru/3.1/library/calendar.html#module-calendar), [`posix`](https://python-all.ru/3.1/library/posix.html#module-posix), [`readline`](https://python-all.ru/3.1/library/readline.html#module-readline), `xmllib`, [`aifc`](https://python-all.ru/3.1/library/aifc.html#module-aifc), `chunk, wave`, [`random`](https://python-all.ru/3.1/library/random.html#module-random), [`shelve`](https://python-all.ru/3.1/library/shelve.html#module-shelve) и [`nntplib`](https://python-all.ru/3.1/library/nntplib.html#module-nntplib). Обратитесь к журналам CVS для получения точной информации об изменениях по каждому патчу.487488Brian Gallew contributed OpenSSL support for the [`socket`](https://python-all.ru/3.1/library/socket.html#module-socket) module. OpenSSL is an implementation of the Secure Socket Layer, which encrypts the data being sent over a socket. When compiling Python, you can edit `Modules/Setup` to include SSL support, which adds an additional function to the [`socket`](https://python-all.ru/3.1/library/socket.html#module-socket) module: `socket.ssl(socket, keyfile, certfile)()`, which takes a socket object and returns an SSL socket. The `httplib` and `urllib` modules were also changed to support `https://` URLs, though no one has implemented FTP or SMTP over SSL.489490Модуль `httplib` был переписан Грегом Штайном для поддержки HTTP/1.1. Обеспечена обратная совместимость с версией 1.5 модуля `httplib`, однако использование возможностей HTTP/1.1, таких как конвейерная обработка, потребует переписывания кода для использования другого набора интерфейсов.491492Модуль `Tkinter` теперь поддерживает Tcl/Tk версий 8.1, 8.2 или 8.3, а поддержка старых версий 7.x была прекращена. Модуль Tkinter теперь поддерживает отображение строк Unicode в виджетах Tk. Кроме того, Фредрик Лунд предоставил оптимизацию, которая делает операции вроде `create_line` и `create_polygon` значительно быстрее, особенно при использовании большого количества координат.493494Модуль [`curses`](https://python-all.ru/3.1/library/curses.html#module-curses) был значительно расширен, начиная с улучшенной версии Оливера Андрича, чтобы предоставить множество дополнительных функций из ncurses и SYSV curses, таких как цвет, поддержка альтернативных наборов символов, панели (pads) и поддержка мыши. Это означает, что модуль больше не совместим с операционными системами, имеющими только BSD curses, но, похоже, в настоящее время нет поддерживаемых ОС, которые попадают в эту категорию.495496Как упоминалось ранее при обсуждении поддержки Unicode в версии 2.0, базовая реализация регулярных выражений, предоставляемая модулем [`re`](https://python-all.ru/3.1/library/re.html#module-re), была изменена. SRE – новый движок регулярных выражений, написанный Фредриком Лундом и частично финансируемый Hewlett Packard, поддерживает сопоставление как с 8-битными строками, так и с Unicode-строками.497498## Новые модули499500Было добавлено несколько новых модулей. Мы просто перечислим их с краткими описаниями; за подробностями о конкретном модуле обращайтесь к документации версии 2.0.501502- [`atexit`](https://python-all.ru/3.1/library/atexit.html#module-atexit): Для регистрации функций, которые должны вызываться перед завершением интерпретатора Python. Код, который сейчас напрямую устанавливает `sys.exitfunc`, следует изменить, чтобы вместо этого использовать модуль [`atexit`](https://python-all.ru/3.1/library/atexit.html#module-atexit), импортировать [`atexit`](https://python-all.ru/3.1/library/atexit.html#module-atexit) и вызывать [`atexit.register()`](https://python-all.ru/3.1/library/atexit.html#atexit.register) с функцией, которая должна быть вызвана при выходе. (Предоставлено Скипом Монтанаро.)503- [`codecs`](https://python-all.ru/3.1/library/codecs.html#module-codecs), `encodings`, [`unicodedata`](https://python-all.ru/3.1/library/unicodedata.html#module-unicodedata): Добавлены в рамках новой поддержки Unicode.504- [`filecmp`](https://python-all.ru/3.1/library/filecmp.html#module-filecmp): Заменяет старые модули `cmp`, `cmpcache` и `dircmp`, которые теперь стали устаревшими. (Предоставлено Гордоном Макмилланом и Моше Задкой.)505- [`gettext`](https://python-all.ru/3.1/library/gettext.html#module-gettext): Этот модуль обеспечивает поддержку интернационализации (I18N) и локализации (L10N) для программ Python, предоставляя интерфейс к библиотеке каталогов сообщений GNU gettext. (Интегрирован Барри Варшавой на основе отдельных вкладов Мартина фон Лёвиса, Питера Фанка и Джеймса Хенстриджа.)506- `linuxaudiodev`: Поддержка устройства `/dev/audio` в Linux, аналог существующего модуля `sunaudiodev`. (Предоставлено Питером Бошем, с исправлениями Джереми Хилтона.)507- [`mmap`](https://python-all.ru/3.1/library/mmap.html#module-mmap): Интерфейс к файлам, отображаемым в память, как в Windows, так и в Unix. Содержимое файла может быть отображено непосредственно в память, после чего оно ведет себя как изменяемая строка, так что его можно читать и изменять. Их даже можно передавать функциям, ожидающим обычные строки, например модулю [`re`](https://python-all.ru/3.1/library/re.html#module-re). (Предоставлено Сэмом Рашингом, с некоторыми расширениями от А.М. Кучлинга.)508- `pyexpat`: Интерфейс к XML-парсеру Expat. (Предоставлено Полом Прескодом.)509- `robotparser`: Разбирает файл `robots.txt`, который используется для написания веб-пауков, вежливо избегающих определенных областей веб-сайта. Парсер принимает содержимое файла `robots.txt`, строит на его основе набор правил и затем может отвечать на вопросы о возможности загрузки заданного URL. (Предоставлено Скипом Монтанаро.)510- [`tabnanny`](https://python-all.ru/3.1/library/tabnanny.html#module-tabnanny): модуль/скрипт для проверки неоднозначных отступов в исходном коде Python. (Автор: Tim Peters.)511- `UserString`: базовый класс для создания объектов, ведущих себя как строки.512- [`webbrowser`](https://python-all.ru/3.1/library/webbrowser.html#module-webbrowser): A module that provides a platform independent way to launch a web browser on a specific URL. For each platform, various browsers are tried in a specific order. The user can alter which browser is launched by setting the *BROWSER* environment variable. (Originally inspired by Eric S. Raymond’s patch to `urllib` which added similar functionality, but the final module comes from code originally implemented by Fred Drake as `Tools/idle/BrowserControl.py`, and adapted for the standard library by Fred.)513- `_winreg`: интерфейс к реестру Windows. `_winreg` – это адаптация функций, входивших в состав PythonWin с 1995 года, но теперь добавленных в основной дистрибутив и расширенных для поддержки Unicode. `_winreg` был написан Биллом Таттом и Марком Хаммондом.514- [`zipfile`](https://python-all.ru/3.1/library/zipfile.html#module-zipfile): модуль для чтения и записи архивов в формате ZIP. Это архивы, созданные программой **PKZIP** на DOS/Windows или **zip** на Unix; не путать с файлами формата **gzip** (которые поддерживаются модулем [`gzip`](https://python-all.ru/3.1/library/gzip.html#module-gzip)). (Автор: James C. Ahlstrom.)515- `imputil`: модуль, предоставляющий более простой способ написания настраиваемых хуков импорта по сравнению с существующим модулем `ihooks`. (Реализован Грегом Стайном при активном обсуждении в python-dev.)516517## Улучшения IDLE518519IDLE – официальная кроссплатформенная среда разработки Python, написанная с использованием Tkinter. Python 2.0 включает IDLE 0.6, в котором добавлен ряд новых возможностей и улучшений. Частичный список:520521- Улучшения и оптимизации интерфейса, особенно в области подсветки синтаксиса и автоматических отступов.522- Браузер классов теперь показывает больше информации, например, функции верхнего уровня в модуле.523- Ширина табуляции теперь настраивается пользователем. При открытии существующего файла Python IDLE автоматически определяет соглашения об отступах и адаптируется.524- Теперь поддерживается вызов браузеров на различных платформах для открытия документации Python в браузере.525- IDLE теперь имеет командную строку, в значительной степени подобную стандартному интерпретатору Python.526- Подсказки вызова (call tips) добавлены во многих местах.527- IDLE теперь можно установить как пакет.528- В окне редактора теперь внизу отображается строка/столбец.529- Три новые команды быстрого вызова: Check module (Alt-F5), Import module (F5) и Run script (Ctrl-F5).530531## Удалённые и устаревшие модули532533Несколько модулей были удалены, так как они устарели или теперь есть более хорошие способы делать то же самое. Модуль `stdwin` исчез; он был предназначен для платформонезависимого оконного набора инструментов, который больше не развивается.534535Ряд модулей был перемещён в подкаталог `lib-old`: `cmp`, `cmpcache`, `dircmp`, `dump`, `find`, `grep`, `packmail`, `poly`, `util`, `whatsound`, `zmod`. Если у вас есть код, который зависит от модуля, перемещённого в `lib-old`, вы можете просто добавить этот каталог в `sys.path`, чтобы вернуть их, но рекомендуется обновить любой код, использующий эти модули.536537## Благодарности538539Авторы хотели бы поблагодарить следующих людей за предложения по различным черновикам этой статьи: Дэвид Болен, Марк Хаммонд, Грегг Хаузер, Джереми Хилтон, Фредрик Лунд, Детлеф Ланнерт, Ааз Марук, Скип Монтанаро, Владимир Марангозов, Тобиас Полцин, Гвидо ван Россум, Нил Шеменауэр и Расс Шмидт.540