Содержание страницы
Что нового в Python 2.0¶What’s New in Python 2.0
| Автор: | A.M. Kuchling and Moshe Zadka |
|---|
Введение¶Introduction
Новый выпуск Python, версия 2.0, был выпущен 16 октября 2000 года. В этой статье рассматриваются захватывающие новые возможности версии 2.0, освещаются некоторые другие полезные изменения и указываются несколько несовместимых изменений, которые могут потребовать переписывания кода.
Разработка Python никогда не прекращается полностью между релизами – в неё постоянно поступает непрерывный поток исправлений ошибок и улучшений. В версию 2.0 вошло множество мелких исправлений, несколько оптимизаций, дополнительные строки документации и более качественные сообщения об ошибках; перечислить их все невозможно, но они, безусловно, важны. Если хотите увидеть полный список, обратитесь к общедоступным журналам CVS. Этот прогресс стал возможен благодаря пяти разработчикам, работающим в PythonLabs, которые теперь получают зарплату за то, что целыми днями исправляют ошибки, а также благодаря улучшению коммуникации после перехода на SourceForge.
Что насчёт Python 1.6?¶What About Python 1.6?
Python 1.6 можно считать релизом Python по договорным обязательствам. После того как основная команда разработчиков покинула CNRI в мае 2000 года, CNRI потребовала создать релиз 1.6, содержащий всю работу над Python, которая была выполнена в CNRI. Таким образом, Python 1.6 представляет состояние дерева CVS по состоянию на май 2000 года, причём наиболее значимой новой функцией является поддержка Unicode. Разработка, конечно, продолжалась и после мая, поэтому дерево 1.6 получило несколько исправлений для обеспечения прямой совместимости с Python 2.0. Поэтому 1.6 является частью эволюции Python, а не побочной ветвью.
Стоит ли проявлять большой интерес к Python 1.6? Вероятно, нет. Релизы 1.6final и 2.0beta1 вышли в один день (5 сентября 2000 года), и планировалось завершить Python 2.0 примерно через месяц. Если у вас есть приложения, которые нужно поддерживать, то вряд ли есть смысл всё ломать переходом на 1.6, исправлять их, а затем снова ломать через месяц переходом на 2.0; лучше сразу перейти на 2.0. Большинство действительно интересных функций, описанных в этом документе, есть только в 2.0, потому что между маем и сентябрём было проделано много работы.
Новый процесс разработки¶New Development Process
Самое значительное изменение в Python 2.0 может быть вовсе не в коде, а в том, как разрабатывается Python: в мае 2000 года разработчики Python начали использовать инструменты, предоставленные SourceForge для хранения исходного кода, отслеживания сообщений об ошибках и управления очередью патчей. Чтобы сообщить об ошибке или отправить патч для Python 2.0, используйте средства отслеживания ошибок и управления патчами, доступные на странице проекта Python по адресу http://sourceforge.net/projects/python/.
Самая важная из служб, теперь размещённых на SourceForge, – это дерево CVS Python, репозиторий с контролем версий, содержащий исходный код Python. Раньше доступ на запись к дереву CVS имели примерно 7 человек, и все патчи должен был просматривать и принимать один из участников этого короткого списка. Очевидно, это было не очень масштабируемо. Перенеся дерево CVS на SourceForge, стало возможным предоставить доступ на запись большему числу людей; по состоянию на сентябрь 2000 года 27 человек могли вносить изменения, что в четыре раза больше. Это делает возможными крупномасштабные изменения, которые не были бы предприняты, если бы их приходилось фильтровать через небольшую группу основных разработчиков. Например, однажды Петер Шнайдер-Камп решил отказаться от совместимости с K&R C и преобразовать исходный код C для Python в ANSI C. Получив одобрение в списке рассылки python-dev, он начал серию коммитов, которая длилась около недели, к нему присоединились другие разработчики, и работа была выполнена. Если бы доступ на запись был только у 5 человек, вероятно, эта задача была бы сочтена «хорошей, но не стоящей затрат времени и усилий» и никогда не была бы выполнена.
Переход на использование служб SourceForge привёл к заметному увеличению скорости разработки. Теперь патчи отправляются, комментируются, дорабатываются людьми, отличными от первоначального отправителя, и пересылаются между людьми до тех пор, пока патч не будет признан достойным включения. Ошибки отслеживаются в одном центральном месте и могут быть назначены конкретному человеку для исправления, и мы можем подсчитывать количество открытых ошибок для измерения прогресса. Это не обошлось без затрат: теперь разработчикам приходится иметь дело с большим объёмом электронной почты, следить за большим количеством списков рассылки, и для новой среды пришлось написать специальные инструменты. Например, SourceForge отправляет стандартные уведомления о патчах и ошибках, которые совершенно бесполезны, поэтому Ка-Пинг Йи написал HTML-скрейпер, который отправляет более полезные сообщения.
Лёгкость добавления кода вызвала некоторые первоначальные трудности роста, например, код принимался до того, как был готов, или без чёткого согласия группы разработчиков. Процесс утверждения, который возник, несколько похож на тот, что используется в группе Apache. Разработчики могут голосовать +1, +0, -0 или -1 за патч; +1 и -1 означают принятие или отклонение, тогда как +0 и -0 означают, что разработчику в основном безразлично это изменение, хотя с лёгким положительным или отрицательным оттенком. Наиболее существенное отличие от модели Apache заключается в том, что голосование носит в основном рекомендательный характер, позволяя Гвидо ван Россуму, имеющему статус Benevolent Dictator For Life (великодушный пожизненный диктатор), узнать общее мнение. Он всё ещё может игнорировать результаты голосования и одобрять или отклонять изменения, даже если сообщество с ним не согласно.
Создание готового патча – последний шаг при добавлении новой возможности, и обычно он проще, чем предшествующая задача разработки хорошего дизайна. Обсуждения новых возможностей нередко раздуваются до длинных обсуждений в списках рассылки, из-за чего за обсуждением становится трудно следить; да и никто не может прочитать каждое сообщение в python-dev. Поэтому был создан относительно формальный процесс написания предложений по улучшению Python (PEP), построенный по образцу процесса RFC в Интернете. PEP – это черновые документы, описывающие предлагаемую новую возможность; они постоянно дорабатываются, пока сообщество не придет к консенсусу, принимая или отклоняя предложение. Цитируя введение к PEP 1, “PEP Purpose and Guidelines”:
PEP означает Python Enhancement Proposal (предложение по улучшению Python). PEP – это проектный документ, предоставляющий информацию сообществу Python или описывающий новую возможность для Python. PEP должен содержать краткую техническую спецификацию функции и обоснование этой функции.
Мы предполагаем, что PEP будут основным механизмом предложения новых функций, сбора мнений сообщества по вопросу и документирования проектных решений, принятых в Python. Автор PEP отвечает за достижение консенсуса в сообществе и документирование разногласий.
Остальную часть PEP 1 читайте для подробностей о редакторском процессе, стиле и формате PEP. PEP хранятся в дереве CVS Python на SourceForge, хотя они не являются частью дистрибутива Python 2.0, а также доступны в HTML-форме на http://www.python.org/peps/. По состоянию на сентябрь 2000 года существует 25 PEP – от PEP 201 «Lockstep Iteration» до PEP 225 «Elementwise/Objectwise Operators».
Юникод¶Unicode
Самая большая новая функция в Python 2.0 – это новый фундаментальный тип данных: строки Unicode. В Unicode для представления символов используются 16-битные числа вместо 8-битных, используемых в ASCII, что означает поддержку 65 536 различных символов.
Окончательный интерфейс поддержки Unicode был разработан в ходе бесчисленных, часто бурных обсуждений в списке рассылки python-dev и в основном реализован Марком-Андре Лембургом на основе реализации строкового типа Unicode Фредрика Лунда. Подробное описание интерфейса было оформлено как PEP 100, «Python Unicode Integration». В этой статье будут рассмотрены лишь наиболее важные моменты, касающиеся интерфейсов Unicode.
В исходном коде Python строки Unicode записываются как u"string". Произвольные символы Unicode можно записать с помощью новой управляющей последовательности \uHHHH, где HHHH – 4-значное шестнадцатеричное число от 0000 до FFFF. Существующая управляющая последовательность \xHHHH также может использоваться, а восьмеричные последовательности можно применять для символов до U+01FF, что обозначается \777.
Строки Unicode, как и обычные строки, являются неизменяемым типом последовательности. Их можно индексировать и нарезать, но нельзя изменять на месте. Строки Unicode имеют метод encode( [encoding] ), который возвращает 8-битную строку в нужной кодировке. Кодировки задаются строками, например 'ascii', 'utf-8', 'iso-8859-1' и т.д. Определён API кодеков для реализации и регистрации новых кодировок, которые затем доступны во всей программе на Python. Если кодировка не указана, по умолчанию используется 7-битная ASCII, хотя её можно изменить для вашей установки Python, вызвав функцию sys.setdefaultencoding(encoding) в изменённой версии site.py.
Объединение 8-битных и Unicode строк всегда приводит к Unicode с использованием кодировки ASCII по умолчанию; результатом 'a' + u'bc' является u'abc'.
Были добавлены новые встроенные функции, а существующие встроенные функции изменены для поддержки Unicode:
- unichr(ch) возвращает строку Unicode длиной в 1 символ, содержащую символ ch.
- ord(u), где u – это обычная или Unicode строка длиной в 1 символ, возвращает номер символа в виде целого числа.
- unicode(string [, encoding] [, errors] ) создаёт строку Unicode из 8-битной строки. encoding – это строка, задающая используемую кодировку. Параметр errors определяет обработку символов, недопустимых для текущей кодировки; передача значения 'strict' приводит к возникновению исключения при любой ошибке кодирования, тогда как 'ignore' вызывает игнорирование ошибок, а 'replace' использует U+FFFD, официальный заменяющий символ, в случае проблем.
- Инструкция exec и различные встроенные функции, такие как eval(), getattr() и setattr(), также будут принимать строки Unicode наравне с обычными строками. (Возможно, в процессе исправления были пропущены некоторые встроенные функции; если вы найдёте встроенную функцию, которая принимает строки, но совсем не принимает строки Unicode, сообщите об этом как об ошибке.)
Новый модуль unicodedata предоставляет интерфейс к свойствам символов Unicode. Например, unicodedata.category(u'A') возвращает строку из двух символов «Lu», где «L» означает букву, а «u» – что она в верхнем регистре. unicodedata.bidirectional(u'\u0660') возвращает «AN», что означает, что U+0660 является арабской цифрой.
Модуль codecs содержит функции для поиска существующих кодировок и регистрации новых. Если вы не собираетесь реализовывать новую кодировку, чаще всего вы будете использовать функцию codecs.lookup(encoding), которая возвращает кортеж из 4 элементов: (encode_func, decode_func, stream_reader, stream_writer).
- encode_func – это функция, которая принимает строку Unicode и возвращает кортеж из двух элементов (string, length). string – это 8-битная строка, содержащая часть (возможно, всю) строки Unicode, преобразованную в заданную кодировку, а length указывает, какая часть строки Unicode была преобразована.
- decode_func – противоположность encode_func; она принимает 8-битную строку и возвращает кортеж из двух элементов (ustring, length), состоящий из результирующей строки Unicode ustring и целого числа length, указывающего, сколько 8-битной строки было обработано.
- stream_reader – это класс, поддерживающий декодирование входных данных из потока. stream_reader(file_obj) возвращает объект, который поддерживает методы read(), readline() и readlines(). Все эти методы будут преобразовывать из заданной кодировки и возвращать строки Unicode.
- stream_writer, аналогично, – это класс, поддерживающий кодирование выходных данных в поток. stream_writer(file_obj) возвращает объект, который поддерживает методы write() и writelines(). Эти методы ожидают строки Unicode и преобразуют их в заданную кодировку при выводе.
Например, следующий код записывает строку Unicode в файл, кодируя её в UTF-8:
import codecs
unistr = u'\u0660\u2000ab ...'
(UTF8_encode, UTF8_decode,
UTF8_streamreader, UTF8_streamwriter) = codecs.lookup('UTF-8')
output = UTF8_streamwriter( open( '/tmp/output', 'wb') )
output.write( unistr )
output.close()
Следующий код затем читает входные данные в UTF-8 из файла:
input = UTF8_streamreader( open( '/tmp/output', 'rb') )
print repr(input.read())
input.close()
Регулярные выражения с поддержкой Unicode доступны через модуль re, который имеет новую базовую реализацию под названием SRE, написанную Фредриком Лундом из Secret Labs AB.
Был добавлен параметр командной строки -U, который заставляет компилятор Python интерпретировать все строковые литералы как литералы строк Unicode. Это предназначено для использования при тестировании и подготовке вашего кода Python к будущим версиям, поскольку в какой-то будущей версии Python может быть прекращена поддержка 8-битных строк и останутся только строки Unicode.
Списочные включения¶List Comprehensions
Списки – это основной тип данных в Python, и многие программы так или иначе работают со списками. Две распространённые операции над списками – это перебор элементов с выбором тех, которые удовлетворяют определённому условию, или применение некоторой функции к каждому элементу. Например, имея список строк, можно захотеть извлечь все строки, содержащие заданную подстроку, или удалить завершающие пробелы в каждой строке.
Существующие функции map() и filter() могут использоваться для этой цели, но они требуют в качестве одного из аргументов функцию. Это нормально, если существует готовая встроенная функция, которую можно передать напрямую, но если её нет, приходится создавать небольшую функцию для выполнения требуемой работы, и правила областей видимости Python делают результат некрасивым, если маленькой функции нужна дополнительная информация. Возьмём первый пример из предыдущего абзаца: поиск всех строк в списке, содержащих заданную подстроку. Можно было бы написать следующее:
# По списку L создать список всех строк
# содержащих подстроку S.
sublist = filter( lambda s, substring=S:
string.find(s, substring) != -1,
L)
Из-за правил области видимости Python используется аргумент по умолчанию, чтобы анонимная функция, созданная инструкцией lambda, знала, какая подстрока ищется. Списковые включения делают это чище:
sublist = [ s for s in L if string.find(s, S) != -1 ]
Списочные включения имеют следующий вид:
[ expression for expr in sequence1
for expr2 in sequence2 ...
for exprN in sequenceN
if condition ]
The for...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 clause is optional; if present, expression is only evaluated and added to the result if condition is true.
Чтобы прояснить семантику, списочное включение эквивалентно следующему коду Python:
for expr1 in sequence1:
for expr2 in sequence2:
...
for exprN in sequenceN:
if (condition):
# Добавить значение
# выражения в
# результирующий список.
Это означает, что при наличии нескольких предложений for...in результирующий список будет равен произведению длин всех последовательностей. Если у вас есть два списка длиной 3, выходной список будет содержать 9 элементов:
seq1 = 'abc'
seq2 = (1,2,3)
>>> [ (x,y) for x in seq1 for y in seq2]
[('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3), ('c', 1),
('c', 2), ('c', 3)]
Чтобы избежать неоднозначности в грамматике Python, если expression создаёт кортеж, его необходимо окружить круглыми скобками. Первое списочное включение ниже содержит синтаксическую ошибку, тогда как второе – корректно:
# Синтаксическая ошибка
[ x,y for x in seq1 for y in seq2]
# Верно
[ (x,y) for x in seq1 for y in seq2]
Идея списковых включений изначально пришла из функционального языка программирования Haskell (http://www.haskell.org). Грег Юинг наиболее убедительно аргументировал их добавление в Python и написал первоначальный патч для списковых включений, который затем обсуждался, казалось, бесконечно долго в списке рассылки python-dev и поддерживался в актуальном состоянии Скипом Монтанаро.
Составное присваивание¶Augmented Assignment
Составные операторы присваивания, ещё одна давно запрашиваемая возможность, были добавлены в Python 2.0. Составные операторы присваивания включают +=, -=, *= и так далее. Например, инструкция a += 2 увеличивает значение переменной a на 2, что эквивалентно чуть более длинной записи a = a + 2.
Полный список поддерживаемых операторов присваивания: +=, -=, *=, /=, %=, **=, &=, |=, ^=, >>= и <<=. Классы Python могут переопределять составные операторы присваивания, определяя методы с именами __iadd__(), __isub__() и т.д. Например, следующий класс Number хранит число и поддерживает использование += для создания нового экземпляра с увеличенным значением.
class Number:
def __init__(self, value):
self.value = value
def __iadd__(self, increment):
return Number( self.value + increment)
n = Number(5)
n += 3
print n.value
Специальный метод __iadd__() вызывается со значением приращения и должен возвращать новый экземпляр с соответствующим изменённым значением; это возвращаемое значение связывается как новое значение переменной в левой части.
Операторы составного присваивания были впервые введены в языке программирования C, и большинство языков, производных от C, такие как awk, C++, Java, Perl и PHP, также их поддерживают. Патч для составного присваивания был реализован Томасом Ваутерсом.
Методы строк¶String Methods
До сих пор функциональность для работы со строками находилась в модуле string, который обычно был внешним интерфейсом для написанного на C модуля strop. Добавление Unicode создало трудность для модуля strop, потому что все функции нужно было бы переписать, чтобы они принимали как 8-битные, так и Unicode строки. Для таких функций, как string.replace(), которая принимает 3 строковых аргумента, это означает восемь возможных перестановок и, соответственно, сложный код.
Вместо этого Python 2.0 перекладывает проблему на строковый тип, делая функциональность для работы со строками доступной через методы как для 8-битных строк, так и для строк Unicode.
>>> 'andrew'.capitalize()
'Andrew'
>>> 'hostname'.replace('os', 'linux')
'hlinuxtname'
>>> 'moshe'.find('sh')
2
Одна вещь, которая не изменилась, несмотря на известную первоапрельскую шутку, – это то, что строки Python неизменяемы. Таким образом, строковые методы возвращают новые строки и не изменяют строку, к которой они применяются.
Старый модуль string всё ещё существует для обратной совместимости, но в основном он выступает в качестве внешнего интерфейса к новым строковым методам.
Два метода, не имеющие аналогов в версиях до 2.0 (хотя они существовали в JPython уже довольно давно): startswith() и endswith(). s.startswith(t) эквивалентно s[:len(t)] == t, а s.endswith(t) эквивалентно s[-len(t):] == t.
Ещё один метод, заслуживающий особого упоминания, – это join(). Метод join() строки принимает один параметр – последовательность строк – и эквивалентен функции string.join() из старого модуля string, но с обратным порядком аргументов. Другими словами, s.join(seq) эквивалентно старой записи string.join(seq, s).
Сборка мусора циклических ссылок¶Garbage Collection of Cycles
Реализация Python на C использует подсчёт ссылок для реализации сборки мусора. Каждый объект Python хранит счётчик количества ссылок, указывающих на него, и обновляет этот счётчик при создании или удалении ссылок. Когда счётчик ссылок достигает нуля, объект становится недоступным, поскольку для доступа к объекту необходима ссылка на него, а если счётчик равен нулю, ссылок больше не существует.
Подсчёт ссылок имеет ряд приятных свойств: его легко понять и реализовать, а результирующая реализация является переносимой, достаточно быстрой и хорошо взаимодействует с другими библиотеками, реализующими собственные схемы управления памятью. Основная проблема подсчёта ссылок заключается в том, что он иногда не замечает, что объекты стали недоступными, что приводит к утечке памяти. Это происходит при наличии циклических ссылок.
Рассмотрим простейший возможный цикл – экземпляр класса, который содержит ссылку на самого себя:
instance = SomeClass()
instance.myself = instance
После выполнения двух указанных выше строк кода счетчик ссылок на instance равен 2; одна ссылка – от переменной с именем 'instance', а другая – от атрибута myself экземпляра.
Если следующей строкой кода будет del instance, что произойдет? Счетчик ссылок instance уменьшится на 1, так что он станет равен 1; ссылка в атрибуте myself все еще существует. Однако экземпляр больше недоступен через код Python и может быть удален. Несколько объектов могут образовывать цикл, если они ссылаются друг на друга, что приводит к утечке всех объектов.
Python 2.0 исправляет эту проблему, периодически выполняя алгоритм обнаружения циклов, который ищет недоступные циклы и удаляет задействованные объекты. Новый модуль gc предоставляет функции для сборки мусора, получения отладочной статистики и настройки параметров сборщика.
Выполнение алгоритма обнаружения циклов требует некоторого времени, поэтому приводит к дополнительным накладным расходам. Предполагается, что после получения опыта работы со сборкой циклов в Python 2.0, Python 2.1 сможет минимизировать накладные расходы за счет тщательной настройки. Пока не очевидно, насколько падает производительность, потому что бенчмаркинг этой задачи сложен и сильно зависит от того, как часто программа создает и уничтожает объекты. Обнаружение циклов можно отключить при компиляции Python, если вы не можете позволить себе даже малейшего снижения скорости или подозреваете, что сборка циклов ошибочна, указав флаг --without-cycle-gc при запуске сценария configure.
Несколько человек взялись за эту проблему и внесли свой вклад в решение. Ранняя реализация подхода с обнаружением циклов была написана Тоби Келси. Текущий алгоритм предложил Эрик Тидерманн во время визита в CNRI, а Гвидо ван Россум и Нил Шеменауэр написали две разные реализации, которые позже были объединены Нилом. Многие другие люди высказывали предложения по ходу дела; в архивах марта 2000 года списка рассылки python-dev содержится большая часть соответствующих обсуждений, особенно в темах «Reference cycle collection for Python» и «Finalization again».
Другие основные изменения¶Other Core Changes
В синтаксис и встроенные функции Python был внесён ряд небольших изменений. Ни одно из них не является очень масштабным, но все они представляют собой удобные возможности.
Небольшие изменения языка¶Minor Language Changes
Новый синтаксис упрощает вызов функции с кортежем аргументов и/или словарем именованных аргументов. В Python 1.5 и ранее для этого использовалась встроенная функция apply(): apply(f, args, kw) вызывает функцию f() с кортежем аргументов args и именованными аргументами из словаря kw. apply() осталась и в 2.0, но благодаря патчу от Грега Юинга f(*args, **kw) стал более коротким и понятным способом достичь того же эффекта. Этот синтаксис симметричен синтаксису определения функций:
def f(*args, **kw):
# args – это кортеж позиционных аргументов,
# kw – это словарь именованных аргументов
...
The 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:
print >> sys.stderr, "Warning: action field not supplied"
Модули теперь можно переименовывать при импорте, используя синтаксис import module as name или from module import name as othername. Патч был представлен Томасом Ваутерсом.
Новый стиль форматирования доступен при использовании оператора %; ‘%r’ вставляет repr() своего аргумента. Это было добавлено из соображений симметрии, на этот раз с существующим стилем ‘%s’, который вставляет str() своего аргумента. Например, '%r %s' % ('abc', 'abc') возвращает строку, содержащую 'abc' abc.
Раньше не было возможности реализовать класс, переопределяющий встроенный оператор in Python и реализующий собственную версию. obj in seq возвращает true, если obj присутствует в последовательности seq; Python вычисляет это, просто перебирая все индексы последовательности, пока не будет найден obj или не возникнет IndexError. Моше Задка представил патч, добавляющий магический метод __contains__() для предоставления собственной реализации оператора in. Кроме того, новые встроенные объекты, написанные на C, могут определять, что для них означает in, через новый слот в протоколе последовательностей.
Более ранние версии Python использовали рекурсивный алгоритм для удаления объектов. Глубоко вложенные структуры данных могли привести к переполнению C-стека интерпретатора и аварийному завершению; Кристиан Тисмер переписал логику удаления, чтобы исправить эту проблему. Похожим образом, сравнение рекурсивных объектов приводило к бесконечной рекурсии и краху; Джереми Хилтон переписал код так, чтобы он больше не падал, а выдавал полезный результат. Например, после этого кода:
a = []
b = []
a.append(a)
b.append(b)
Сравнение a==b возвращает true, потому что две рекурсивные структуры данных изоморфны. См. обсуждение в теме «trashcan and PR#7» в архивах апреля 2000 года списка рассылки python-dev, где велась дискуссия, приведшая к этой реализации, а также полезные ссылки. Обратите внимание: теперь сравнения также могут вызывать исключения. В более ранних версиях Python операция сравнения, например cmp(a,b), всегда давала ответ, даже если пользовательский метод __cmp__() сталкивался с ошибкой, так как возникшее исключение просто молча проглатывалось.
Проведена работа по портированию Python на 64-разрядную Windows на процессоре Itanium, в основном Трентом Миком из ActiveState. (Как ни странно, sys.platform по-прежнему 'win32' на Win64, поскольку, похоже, для упрощения портирования MS Visual C++ обрабатывает код как 32-разрядный на Itanium.) PythonWin также поддерживает Windows CE; дополнительную информацию см. на странице Python CE по адресу http://pythonce.sourceforge.net/.
Ещё одна новая платформа – Darwin/MacOS X; начальная поддержка для неё появилась в Python 2.0. Динамическая загрузка работает, если указать «configure –with-dyld –with-suffix=.x». За дополнительными инструкциями обращайтесь к файлу README в дистрибутиве исходного кода Python.
Была предпринята попытка смягчить один из недостатков Python – часто сбивающее с толку исключение NameError, когда код обращается к локальной переменной до того, как ей присвоено значение. Например, следующий код вызывает исключение на операторе print как в 1.5.2, так и в 2.0; в 1.5.2 возбуждается исключение NameError, а в 2.0 – новое исключение UnboundLocalError. UnboundLocalError является подклассом NameError, поэтому любой существующий код, ожидающий возбуждения NameError, по-прежнему должен работать.
def f():
print "i=",i
i = i + 1
f()
Введены два новых исключения: TabError и IndentationError. Оба являются подклассами SyntaxError и возбуждаются, когда код Python имеет неправильные отступы.
Изменения во встроенных функциях¶Changes to Built-in Functions
Добавлена новая встроенная функция zip(seq1, seq2, ...). zip() возвращает список кортежей, где каждый кортеж содержит i-й элемент из каждой последовательности-аргумента. Разница между zip() и map(None, seq1, seq2) в том, что map() дополняет последовательности значением None, если они не одинаковой длины, а zip() укорачивает возвращаемый список до длины самой короткой последовательности.
Функции int() и long() теперь принимают необязательный параметр «base», если первый аргумент является строкой. int('123', 10) возвращает 123, а int('123', 16) возвращает 291. int(123, 16) возбуждает исключение TypeError с сообщением «can't convert non-string with explicit base».
В модуль sys добавлена новая переменная, содержащая более подробную информацию о версии. sys.version_info – это кортеж (major, minor, micro, level, serial). Например, в гипотетической версии 2.0.1beta1 значение sys.version_info было бы (2, 0, 1, 'beta', 1). level – это строка, например "alpha", "beta" или "final" для окончательного релиза.
У словарей появился новый необычный метод setdefault(key, default), который ведет себя аналогично существующему методу get(). Однако, если ключ отсутствует, setdefault() не только возвращает значение default, как это сделал бы get(), но и вставляет его в словарь в качестве значения для key. Таким образом, следующие строки кода:
if dict.has_key( key ): return dict[key]
else:
dict[key] = []
return dict[key]
могут быть заменены одним оператором return dict.setdefault(key, []).
Интерпретатор устанавливает максимальную глубину рекурсии, чтобы перехватить неконтролируемую рекурсию до того, как будет заполнен стек C и произойдет дамп ядра или GPF. Ранее этот предел был фиксирован при компиляции Python, но в 2.0 максимальную глубину рекурсии можно читать и изменять с помощью sys.getrecursionlimit() и sys.setrecursionlimit(). Значение по умолчанию – 1000, а приблизительное максимальное значение для данной платформы можно узнать, запустив новый скрипт Misc/find_recursionlimit.py.
Переход на версию 2.0¶Porting to 2.0
Новые релизы Python стараются быть совместимыми с предыдущими, и до сих пор это удавалось довольно хорошо. Однако некоторые изменения считаются достаточно полезными, обычно потому что они исправляют изначальные проектные решения, оказавшиеся ошибочными, и нарушения обратной совместимости не всегда можно избежать. В этом разделе перечислены изменения в Python 2.0, которые могут привести к неработоспособности старого кода.
Изменение, которое, вероятно, сломает больше всего кода, – это ужесточение требований к аргументам, принимаемым некоторыми методами. Некоторые методы раньше принимали несколько аргументов и рассматривали их как кортеж, в частности различные методы списков, такие как append() и insert(). В более ранних версиях Python, если L – список, то L.append( 1,2 ) добавляет кортеж (1,2) в список. В Python 2.0 это вызывает исключение TypeError с сообщением: «append requires exactly 1 argument; 2 given». Исправление состоит в том, чтобы просто добавить дополнительные скобки и передать оба значения как кортеж: L.append( (1,2) ).
Более ранние версии этих методов были более снисходительными, потому что они использовали старую функцию в C-интерфейсе Python для разбора аргументов; в 2.0 они модернизированы для использования PyArg_ParseTuple() – текущей функции разбора аргументов, которая выдает более информативные сообщения об ошибках и считает вызовы с несколькими аргументами ошибочными. Если вы абсолютно вынуждены использовать 2.0, но не можете исправить свой код, вы можете отредактировать Objects/listobject.c и определить символ препроцессора NO_STRICT_LIST_APPEND, чтобы сохранить старое поведение; это не рекомендуется.
Некоторые функции в модуле socket по-прежнему снисходительны в этом отношении. Например, socket.connect( ('hostname', 25) )() – правильная форма, передающая кортеж, представляющий IP-адрес, но socket.connect( 'hostname', 25 )() также работает. socket.connect_ex() и socket.bind() столь же снисходительны. В версии 2.0alpha1 эти функции были ужесточены, но поскольку в документации фактически использовалась ошибочная форма с несколькими аргументами, многие люди написали код, который бы сломался при более строгой проверке. GvR откатил изменения под давлением общественности, поэтому для модуля socket документация была исправлена, а форма с несколькими аргументами просто помечена как устаревшая; в будущей версии Python она будет снова ужесточена.
Управляющая последовательность \x в строковых литералах теперь принимает ровно 2 шестнадцатеричные цифры. Раньше она потребляла все шестнадцатеричные цифры после 'x' и брала младшие 8 бит результата, так что \x123456 было эквивалентно \x56.
Исключения AttributeError и NameError теперь имеют более дружественные сообщения об ошибках, текст которых будет выглядеть примерно так: 'Spam' instance has no attribute 'eggs' или name 'eggs' is not defined. Раньше сообщение об ошибке было просто именем отсутствующего атрибута eggs, и код, написанный с учетом этого, сломается в 2.0.
Проделана определенная работа, чтобы сделать обычные целые числа и длинные целые числа более взаимозаменяемыми. В версии 1.5.2 для Solaris была добавлена поддержка больших файлов, позволяющая читать файлы размером более 2 ГБ; это привело к тому, что метод tell() файловых объектов стал возвращать длинное целое вместо обычного. Некоторый код вычитал два смещения файла и пытался использовать результат для умножения последовательности или среза строки, но это вызывало исключение TypeError. В версии 2.0 длинные целые можно использовать для умножения или среза последовательности, и это будет работать интуитивно ожидаемым образом; 3L * 'abc' дает 'abcabcabc', а (0,1,2,3)[2L:4L] дает (2,3). Длинные целые также можно использовать в различных контекстах, где раньше принимались только целые числа, например в методе seek() файловых объектов и в форматах, поддерживаемых оператором % (%d, %i, %x и т.д.). Например, "%d" % 2L**64 выдаст строку 18446744073709551616.
Самое тонкое изменение, касающееся длинных целых, заключается в том, что результат str() от длинного целого больше не содержит завершающего символа 'L', хотя repr() все еще включает его. 'L' раздражал многих людей, которые хотели печатать длинные целые, выглядевшие как обычные целые, так как им приходилось делать лишние действия, чтобы отрезать этот символ. В версии 2.0 это больше не проблема, но код, который делает str(longval)[:-1] и предполагает, что 'L' присутствует, теперь потеряет последнюю цифру.
Вычисление repr() от числа с плавающей запятой теперь использует другую точность форматирования, чем str(). repr() использует строку формата %.17g для C-функции sprintf(), в то время как str() использует %.12g, как и раньше. Результат в том, что repr() иногда может показывать больше десятичных знаков, чем str(), для некоторых чисел. Например, число 8.1 не может быть точно представлено в двоичном виде, поэтому repr(8.1) равно '8.0999999999999996', а str(8.1) равно '8.1'.
Параметр командной строки -X, который превращал все стандартные исключения в строки вместо классов, был удален; теперь стандартные исключения всегда будут классами. Модуль exceptions, содержащий стандартные исключения, был переведен с Python на встроенный C-модуль, написанный Барри Уорсо и Фредриком Лундом.
Изменения в расширении и встраивании¶Extending/Embedding Changes
Некоторые изменения находятся «под капотом» и будут заметны только тем, кто пишет модули расширения на C или встраивает интерпретатор Python в более крупное приложение. Если вы не работаете с C API Python, можете смело пропустить этот раздел.
Номер версии Python C API был увеличен, поэтому расширения на C, скомпилированные для версии 1.5.2, должны быть перекомпилированы для работы с версией 2.0. В Windows из-за особенностей работы DLL Python 2.0 не может импортировать сторонние расширения, собранные для Python 1.5.x; Python вызовет исключение, и импорт не удастся.
Пользователи модуля ExtensionClass Джима Фултона будут рады узнать, что были добавлены перехватчики, благодаря которым ExtensionClasses теперь поддерживаются функциями isinstance() и issubclass(). Это означает, что больше не нужно помнить о необходимости писать код вроде if type(obj) == myExtensionClass, а можно использовать более естественный if isinstance(obj, myExtensionClass).
The 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.
Долгожданная реструктуризация malloc, выполненная Владимиром Марангозовым, была завершена, чтобы интерпретатор Python мог легко использовать собственный аллокатор вместо стандартного malloc() из C. Документацию см. в комментариях в Include/pymem.h и Include/objimpl.h. За подробными обсуждениями, в ходе которых вырабатывался интерфейс, обращайтесь к веб-архивам списков «patches» и «python-dev» на python.org.
Последние версии среды разработки GUSI для MacOS поддерживают потоки POSIX. Поэтому поддержка потоков POSIX в Python теперь работает на Macintosh. Также была добавлена поддержка потоков с использованием пользовательской библиотеки GNU pth.
Поддержка потоков в Windows также была улучшена. Windows поддерживает блокировки потоков, которые используют объекты ядра только в случае конкуренции; в типичном случае, когда конкуренции нет, используются более простые функции, которые на порядок быстрее. Потоковая версия Python 1.5.2 на NT работает в два раза медленнее однопоточной; с изменениями в 2.0 разница составляет всего 10%. Эти улучшения были внесены Яковом Марковичем.
Исходный код Python 2.0 теперь использует только прототипы ANSI C, поэтому для компиляции Python требуется компилятор ANSI C, и больше нельзя использовать компилятор, поддерживающий только K&R C.
Ранее виртуальная машина Python использовала 16-битные числа в своём байт-коде, что ограничивало размер исходных файлов. В частности, это влияло на максимальный размер литеральных списков и словарей в исходном коде Python; время от времени разработчики, генерирующие код Python, сталкивались с этим ограничением. Патч Чарльза Дж. Уолдмана поднимает предел с 2^16 до 2^{32}.
Было добавлено три новые вспомогательные функции для добавления констант в словарь модуля во время его инициализации: PyModule_AddObject(), PyModule_AddIntConstant() и PyModule_AddStringConstant(). Каждая из этих функций принимает объект модуля, C-строку с нулевым символом в конце, содержащую добавляемое имя, и третий аргумент – значение, присваиваемое этому имени. Этот третий аргумент представляет собой, соответственно, объект Python, значение C long или C-строку.
Добавлен обёрточный API для обработчиков сигналов в стиле Unix. PyOS_getsig() получает обработчик сигнала, а PyOS_setsig() устанавливает новый обработчик.
Distutils: упрощение установки модулей¶Distutils: Making Modules Easy to Install
До Python 2.0 установка модулей была утомительным делом – не было возможности автоматически определить, где установлен Python, или какие параметры компилятора использовать для модулей расширения. Авторам программного обеспечения приходилось проходить через утомительный ритуал редактирования файлов Makefile и конфигурационных файлов, который нормально работал только на Unix и не поддерживал Windows и MacOS. Пользователи Python сталкивались с сильно различающимися инструкциями по установке для разных пакетов расширений, что делало администрирование установки Python довольно обременительным.
Специальная группа по дистрибуции (SIG), руководимая Грегом Уордом, создала Distutils – систему, значительно упрощающую установку пакетов. Они образуют пакет distutils, новую часть стандартной библиотеки Python. В лучшем случае установка модуля Python из исходников потребует одних и тех же действий: сначала просто распаковать tar-архив или zip-архив, а затем выполнить «python setup.py install». Платформа будет определена автоматически, компилятор распознан, модули-расширения на C скомпилированы, а дистрибутив установлен в нужный каталог. Дополнительные аргументы командной строки дают больше контроля над процессом установки, пакет distutils предоставляет множество мест для переопределения значений по умолчанию – разделение сборки и установки, сборка или установка в нестандартные каталоги и многое другое.
Чтобы использовать Distutils, необходимо написать скрипт setup.py. В простейшем случае, когда программа содержит только .py-файлы, минимальный setup.py может состоять всего из нескольких строк:
from distutils.core import setup
setup (name = "foo", version = "1.0",
py_modules = ["module1", "module2"])
Файл setup.py ненамного сложнее, если программа состоит из нескольких пакетов:
from distutils.core import setup
setup (name = "foo", version = "1.0",
packages = ["package", "package.subpackage"])
Расширение на C может быть самым сложным случаем; вот пример, взятый из пакета PyXML:
from distutils.core import setup, Extension
expat_extension = Extension('xml.parsers.pyexpat',
define_macros = [('XML_NS', None)],
include_dirs = [ 'extensions/expat/xmltok',
'extensions/expat/xmlparse' ],
sources = [ 'extensions/pyexpat.c',
'extensions/expat/xmltok/xmltok.c',
'extensions/expat/xmltok/xmlrole.c', ]
)
setup (name = "PyXML", version = "0.5.4",
ext_modules =[ expat_extension ] )
Distutils также может создавать исходные и бинарные дистрибутивы. Команда «sdist», запускаемая как «python setup.py sdist», собирает исходный дистрибутив, например foo-1.0.tar.gz. Добавлять новые команды несложно; команды «bdist_rpm» и «bdist_wininst» уже были предоставлены для создания RPM-дистрибутива и установщика для Windows соответственно. Команды для создания других форматов дистрибутивов, таких как пакеты Debian и файлы Solaris .pkg, находятся на разных стадиях разработки.
Всё это описано в новом руководстве Distributing Python Modules, которое пополняет основной набор документации Python.
Модули XML¶XML Modules
Python 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 SIG также работает над улучшенной документацией.
Поддержка SAX2¶SAX2 Support
SAX определяет событийно-ориентированный интерфейс для разбора XML. Чтобы использовать SAX, необходимо написать класс-обработчик SAX. Классы-обработчики наследуются от различных классов, предоставляемых SAX, и переопределяют различные методы, которые затем вызываются XML-парсером. Например, методы startElement() и endElement() вызываются для каждого открывающего и закрывающего тега, встреченных парсером, метод characters() вызывается для каждого фрагмента символьных данных и так далее.
Преимущество событийно-ориентированного подхода в том, что весь документ не должен постоянно находиться в памяти, что важно при обработке действительно огромных документов. Однако написание класса-обработчика SAX может сильно усложниться, если вы пытаетесь модифицировать структуру документа каким-либо сложным образом.
Например, эта небольшая программа определяет обработчик, который выводит сообщение для каждого открывающего и закрывающего тега, а затем разбирает файл hamlet.xml с его помощью:
from xml import sax
class SimpleHandler(sax.ContentHandler):
def startElement(self, name, attrs):
print 'Start of element:', name, attrs.keys()
def endElement(self, name):
print 'End of element:', name
# Создать объект парсера
parser = sax.make_parser()
# Указать ему, какой обработчик использовать
handler = SimpleHandler()
parser.setContentHandler( handler )
# Разобрать файл!
parser.parse( 'hamlet.xml' )
За дополнительной информацией обращайтесь к документации Python или XML HOWTO по адресу http://pyxml.sourceforge.net/topics/howto/xml-howto.html.
Поддержка DOM¶DOM Support
Document Object Model – это древовидное представление XML-документа. Экземпляр верхнего уровня Document является корнем дерева и имеет единственный дочерний элемент – экземпляр Element верхнего уровня. Этот Element имеет дочерние узлы, представляющие символьные данные и любые подэлементы, которые, в свою очередь, могут иметь собственные дочерние узлы и так далее. Используя DOM, можно обходить полученное дерево любым способом, получать значения элементов и атрибутов, вставлять и удалять узлы, а также преобразовывать дерево обратно в XML.
DOM полезен для изменения XML-документов, поскольку можно создать DOM-дерево, изменить его, добавляя новые узлы или перестраивая поддеревья, а затем получить новый XML-документ на выходе. Также можно вручную построить DOM-дерево и преобразовать его в XML, что может быть более гибким способом создания XML-вывода, чем простая запись <tag1>...</tag1> в файл.
Реализация DOM, входящая в состав Python, находится в модуле xml.dom.minidom. Это облегченная реализация DOM уровня 1 с поддержкой пространств имен XML. Для генерации DOM-дерева предоставляются вспомогательные функции parse() и parseString():
from xml.dom import minidom
doc = minidom.parse('hamlet.xml')
doc – это экземпляр Document. Document, как и все остальные классы DOM, такие как Element и Text, является подклассом базового класса Node. Поэтому все узлы DOM-дерева поддерживают определенные общие методы, например toxml(), который возвращает строку, содержащую XML-представление узла и его дочерних элементов. Каждый класс также имеет свои собственные специальные методы; например, экземпляры Element и Document имеют метод для поиска всех дочерних элементов с заданным именем тега. Продолжая предыдущий пример из двух строк:
perslist = doc.getElementsByTagName( 'PERSONA' )
print perslist[0].toxml()
print perslist[1].toxml()
Для XML-файла Hamlet несколько строк выше выводят:
<PERSONA>CLAUDIUS, king of Denmark. </PERSONA>
<PERSONA>HAMLET, son to the late, and nephew to the present king.</PERSONA>
Корневой элемент документа доступен как doc.documentElement, а его дочерние элементы можно легко изменять, удаляя, добавляя или убирая узлы:
root = doc.documentElement
# Удалить первый дочерний элемент
root.removeChild( root.childNodes[0] )
# Переместить новый первый дочерний элемент в конец
root.appendChild( root.childNodes[0] )
# Вставить новый первый дочерний элемент (изначально
# третий дочерний элемент) перед 20-м дочерним элементом.
root.insertBefore( root.childNodes[0], root.childNodes[20] )
Опять же, обратитесь к документации Python для получения полного списка различных классов Node и их разнообразных методов.
Отношение к PyXML¶Relationship to PyXML
Специальная группа по XML (XML SIG) некоторое время работала над кодом Python для работы с XML. Её дистрибутив кода, называемый PyXML, доступен на веб-страницах группы по адресу http://www.python.org/sigs/xml-sig/. В дистрибутиве PyXML также использовалось имя пакета xml. Если вы писали программы, использующие PyXML, вас, вероятно, интересует его совместимость с пакетом xml версии 2.0.
Ответ таков: пакет xml из Python 2.0 несовместим с PyXML, но эту несовместимость можно устранить, установив последнюю версию PyXML. Многие приложения могут обойтись поддержкой XML, входящей в состав Python 2.0, но более сложные приложения потребуют установки полного пакета PyXML. После установки PyXML версии 0.6.0 или новее заменит пакет xml, поставляемый с Python, и будет строгим надмножеством стандартного пакета, добавляя множество дополнительных возможностей. Некоторые из дополнительных функций PyXML включают:
- 4DOM – полная реализация DOM от FourThought, Inc.
- Валидирующий парсер xmlproc, написанный Ларсом Мариусом Гаршолем.
- Модуль-ускоритель парсера sgmlop, написанный Фредриком Лундом.
Изменения в модулях¶Module changes
В обширную стандартную библиотеку Python было внесено множество улучшений и исправлений; некоторые из затронутых модулей включают readline, ConfigParser, cgi, calendar, posix, readline, xmllib, aifc, chunk, wave, random, shelve и nntplib. Обратитесь к журналам CVS для получения точной информации об изменениях по каждому патчу.
Брайан Галлью предоставил поддержку OpenSSL для модуля socket. OpenSSL – это реализация протокола Secure Socket Layer, шифрующая данные, передаваемые через сокет. При компиляции Python можно отредактировать Modules/Setup, чтобы включить поддержку SSL, что добавляет дополнительную функцию в модуль socket: socket.ssl(socket, keyfile, certfile), которая принимает объект сокета и возвращает SSL-сокет. Модули httplib и urllib также были изменены для поддержки URL-адресов https://, хотя никто не реализовал FTP или SMTP через SSL.
Модуль httplib был переписан Грегом Штайном для поддержки HTTP/1.1. Обеспечена обратная совместимость с версией 1.5 модуля httplib, однако использование возможностей HTTP/1.1, таких как конвейерная обработка, потребует переписывания кода для использования другого набора интерфейсов.
Модуль Tkinter теперь поддерживает Tcl/Tk версий 8.1, 8.2 или 8.3, а поддержка старых версий 7.x была прекращена. Модуль Tkinter теперь поддерживает отображение строк Unicode в виджетах Tk. Кроме того, Фредрик Лунд предоставил оптимизацию, которая делает операции вроде create_line и create_polygon значительно быстрее, особенно при использовании большого количества координат.
Модуль curses был значительно расширен, начиная с улучшенной версии Оливера Андрича, чтобы предоставить множество дополнительных функций из ncurses и SYSV curses, таких как цвет, поддержка альтернативных наборов символов, панели (pads) и поддержка мыши. Это означает, что модуль больше не совместим с операционными системами, имеющими только BSD curses, но, похоже, в настоящее время нет поддерживаемых ОС, которые попадают в эту категорию.
Как упоминалось ранее при обсуждении поддержки Unicode в версии 2.0, базовая реализация регулярных выражений, предоставляемая модулем re, была изменена. SRE – новый движок регулярных выражений, написанный Фредриком Лундом и частично финансируемый Hewlett Packard, поддерживает сопоставление как с 8-битными строками, так и с Unicode-строками.
Новые модули¶New modules
Было добавлено несколько новых модулей. Мы просто перечислим их с краткими описаниями; за подробностями о конкретном модуле обращайтесь к документации версии 2.0.
- atexit: Для регистрации функций, которые должны вызываться перед завершением интерпретатора Python. Код, который сейчас напрямую устанавливает sys.exitfunc, следует изменить, чтобы вместо этого использовать модуль atexit, импортировать atexit и вызывать atexit.register() с функцией, которая должна быть вызвана при выходе. (Предоставлено Скипом Монтанаро.)
- codecs, encodings, unicodedata: Добавлены в рамках новой поддержки Unicode.
- filecmp: Заменяет старые модули cmp, cmpcache и dircmp, которые теперь стали устаревшими. (Предоставлено Гордоном Макмилланом и Моше Задкой.)
- gettext: Этот модуль обеспечивает поддержку интернационализации (I18N) и локализации (L10N) для программ Python, предоставляя интерфейс к библиотеке каталогов сообщений GNU gettext. (Интегрирован Барри Варшавой на основе отдельных вкладов Мартина фон Лёвиса, Питера Фанка и Джеймса Хенстриджа.)
- linuxaudiodev: Поддержка устройства /dev/audio в Linux, аналог существующего модуля sunaudiodev. (Предоставлено Питером Бошем, с исправлениями Джереми Хилтона.)
- mmap: Интерфейс к файлам, отображаемым в память, как в Windows, так и в Unix. Содержимое файла может быть отображено непосредственно в память, после чего оно ведет себя как изменяемая строка, так что его можно читать и изменять. Их даже можно передавать функциям, ожидающим обычные строки, например модулю re. (Предоставлено Сэмом Рашингом, с некоторыми расширениями от А.М. Кучлинга.)
- pyexpat: Интерфейс к XML-парсеру Expat. (Предоставлено Полом Прескодом.)
- robotparser: Разбирает файл robots.txt, который используется для написания веб-пауков, вежливо избегающих определенных областей веб-сайта. Парсер принимает содержимое файла robots.txt, строит на его основе набор правил и затем может отвечать на вопросы о возможности загрузки заданного URL. (Предоставлено Скипом Монтанаро.)
- tabnanny: модуль/скрипт для проверки неоднозначных отступов в исходном коде Python. (Автор: Tim Peters.)
- UserString: базовый класс для создания объектов, ведущих себя как строки.
- webbrowser: модуль, предоставляющий платформонезависимый способ открытия веб-браузера по определённому URL. Для каждой платформы различные браузеры перебираются в определённом порядке. Пользователь может изменить запускаемый браузер, установив переменную окружения BROWSER. (Изначально вдохновлён патчем Эрика С. Раймонда к urllib, который добавлял аналогичную функциональность, но итоговый модуль основан на коде, первоначально реализованном Фредом Дрейком как Tools/idle/BrowserControl.py, и адаптированном для стандартной библиотеки Фредом.)
- _winreg: интерфейс к реестру Windows. _winreg – это адаптация функций, входивших в состав PythonWin с 1995 года, но теперь добавленных в основной дистрибутив и расширенных для поддержки Unicode. _winreg был написан Биллом Таттом и Марком Хаммондом.
- zipfile: модуль для чтения и записи архивов в формате ZIP. Это архивы, созданные программой PKZIP на DOS/Windows или zip на Unix; не путать с файлами формата gzip (которые поддерживаются модулем gzip). (Автор: James C. Ahlstrom.)
- imputil: модуль, предоставляющий более простой способ написания настраиваемых хуков импорта по сравнению с существующим модулем ihooks. (Реализован Грегом Стайном при активном обсуждении в python-dev.)
Улучшения IDLE¶IDLE Improvements
IDLE – официальная кроссплатформенная среда разработки Python, написанная с использованием Tkinter. Python 2.0 включает IDLE 0.6, в котором добавлен ряд новых возможностей и улучшений. Частичный список:
- Улучшения и оптимизации интерфейса, особенно в области подсветки синтаксиса и автоматических отступов.
- Браузер классов теперь показывает больше информации, например, функции верхнего уровня в модуле.
- Ширина табуляции теперь настраивается пользователем. При открытии существующего файла Python IDLE автоматически определяет соглашения об отступах и адаптируется.
- Теперь поддерживается вызов браузеров на различных платформах для открытия документации Python в браузере.
- IDLE теперь имеет командную строку, в значительной степени подобную стандартному интерпретатору Python.
- Подсказки вызова (call tips) добавлены во многих местах.
- IDLE теперь можно установить как пакет.
- В окне редактора теперь внизу отображается строка/столбец.
- Три новые команды быстрого вызова: Check module (Alt-F5), Import module (F5) и Run script (Ctrl-F5).
Удалённые и устаревшие модули¶Deleted and Deprecated Modules
Несколько модулей были удалены, так как они устарели или теперь есть более хорошие способы делать то же самое. Модуль stdwin исчез; он был предназначен для платформонезависимого оконного набора инструментов, который больше не развивается.
Ряд модулей был перемещён в подкаталог lib-old: cmp, cmpcache, dircmp, dump, find, grep, packmail, poly, util, whatsound, zmod. Если у вас есть код, который зависит от модуля, перемещённого в lib-old, вы можете просто добавить этот каталог в sys.path, чтобы вернуть их, но рекомендуется обновить любой код, использующий эти модули.
Благодарности¶Acknowledgements
Авторы хотели бы поблагодарить следующих людей за предложения по различным черновикам этой статьи: Дэвид Болен, Марк Хаммонд, Грегг Хаузер, Джереми Хилтон, Фредрик Лунд, Детлеф Ланнерт, Ааз Марук, Скип Монтанаро, Владимир Марангозов, Тобиас Полцин, Гвидо ван Россум, Нил Шеменауэр и Расс Шмидт.