Що нового в Python 2.0

Автор

A.M. Kuchling та Moshe Zadka

вступ

Новий випуск Python, версія 2.0, був випущений 16 жовтня 2000 року. У цій статті розглядаються цікаві нові можливості версії 2.0, висвітлюються деякі інші корисні зміни та вказується на кілька несумісних змін, які можуть вимагати переписування коду.

Python’s development never completely stops between releases, and a steady flow of bug fixes and improvements are always being submitted. A host of minor fixes, a few optimizations, additional docstrings, and better error messages went into 2.0; to list them all would be impossible, but they’re certainly significant. Consult the publicly-available CVS logs if you want to see the full list. This progress is due to the five developers working for PythonLabs are now getting paid to spend their days fixing bugs, and also due to the improved communication resulting from moving to SourceForge.

Що щодо Python 1.6?

Python 1.6 можна вважати випуском Python Contractual Obligations. Після того, як основна команда розробників залишила 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, оскільки з травня по вересень було виконано багато роботи.

Новий процес розвитку

Найважливіша зміна в Python 2.0 може стосуватися зовсім не коду, а способу розробки Python: у травні 2000 року розробники Python почали використовувати інструменти, надані SourceForge для зберігання вихідного коду, відстеження звітів про помилки та керування чергою. подання патчів. Щоб повідомити про помилки або надіслати виправлення для Python 2.0, використовуйте інструменти відстеження помилок і керування виправленнями, доступні на сторінці проекту Python, розташованій за адресою https://sourceforge.net/projects/python/.

Найважливішою з послуг, які зараз розміщені на SourceForge, є дерево Python CVS, репозиторій з контрольованими версіями, що містить вихідний код для Python. Раніше було приблизно 7 або близько того людей, які мали доступ для запису до дерева CVS, і всі латки повинні були бути перевірені та зареєстровані одним із людей у цьому короткому списку. Очевидно, що це було не дуже масштабовано. Завдяки переміщенню дерева CVS до SourceForge стало можливим надати доступ для запису більшій кількості людей; станом на вересень 2000 року було 27 осіб, які могли перевірити зміни, тобто чотириразове збільшення. Це робить можливими масштабні зміни, які б не були зроблені, якби їх довелося фільтрувати через невелику групу основних розробників. Наприклад, одного разу Пітер Шнайдер-Камп спав на думку відмовитися від сумісності з K&R C і перетворити вихідний код C для Python на ANSI C. Отримавши схвалення в списку розсилки python-dev, він розпочав шквал перевірок, які тривали близько тижня інші розробники приєдналися, щоб допомогти, і роботу було виконано. Якби було лише 5 осіб із доступом для запису, ймовірно, це завдання було б сприйняте як «гарне, але не варте потрібного часу та зусиль», і воно ніколи не було б виконане.

Перехід до використання послуг SourceForge призвів до значного збільшення швидкості розробки. Патчі тепер надсилаються, коментуються, переглядаються людьми, які не були початковим відправником, і обмінюються між людьми, доки виправлення не буде визнано вартим перевірки. Помилки відстежуються в одному центральному місці та можуть бути призначені конкретній особі для виправлення , і ми можемо підрахувати кількість відкритих помилок для вимірювання прогресу. Це не обійшлося без витрат: розробники тепер мають більше електронної пошти, щоб мати справу з більшою кількістю списків розсилки, і для нового середовища потрібно було написати спеціальні інструменти. Наприклад, SourceForge надсилає повідомлення електронною поштою про стандартні виправлення та сповіщення про помилки, які абсолютно марні, тому Ka-Ping Yee написав HTML-скрейпер, який надсилає більш корисні повідомлення.

Легкість додавання коду спричинила кілька початкових труднощів, наприклад код перевірявся до того, як він був готовий, або без отримання чіткої згоди від групи розробників. Процес затвердження, який з’явився, дещо схожий на той, який використовується групою Apache. Розробники можуть голосувати за патч +1, +0, -0 або -1; +1 і -1 означають прийняття або відхилення, тоді як +0 і -0 означають, що розробник здебільшого байдужий до змін, хоча з невеликим позитивним або негативним ухилом. Найсуттєвішою зміною в порівнянні з моделлю Apache є те, що голосування є, по суті, дорадчим, дозволяючи Гвідо ван Россуму, який має статус доброзичливого довічного диктатора, знати, якою є загальна думка. Він все ще може ігнорувати результати голосування та схвалити або відхилити зміни, навіть якщо спільнота з ним не погоджується.

Producing an actual patch is the last step in adding a new feature, and is usually easy compared to the earlier task of coming up with a good design. Discussions of new features can often explode into lengthy mailing list threads, making the discussion hard to follow, and no one can read every posting to python-dev. Therefore, a relatively formal process has been set up to write Python Enhancement Proposals (PEPs), modelled on the Internet RFC process. PEPs are draft documents that describe a proposed new feature, and are continually revised until the community reaches a consensus, either accepting or rejecting the proposal. Quoting from the introduction to PEP 1, «PEP Purpose and Guidelines»:

PEP розшифровується як Python Enhancement Proposal. PEP — це проектний документ, який надає інформацію спільноті Python або описує нову функцію для Python. PEP має надавати стислу технічну специфікацію функції та обґрунтування цієї функції.

Ми плануємо, щоб PEP були основними механізмами для пропонування нових функцій, для збору внесків спільноти щодо проблеми та для документування дизайнерських рішень, які увійшли до Python. Автор PEP відповідає за формування консенсусу в спільноті та документування особливих думок.

Read the rest of PEP 1 for the details of the PEP editorial process, style, and format. PEPs are kept in the Python CVS tree on SourceForge, though they’re not part of the Python 2.0 distribution, and are also available in HTML form from https://www.python.org/dev/peps/. As of September 2000, there are 25 PEPS, ranging from PEP 201, «Lockstep Iteration», to PEP 225, «Elementwise/Objectwise Operators».

Unicode

Найбільшою новою функцією Python 2.0 є новий фундаментальний тип даних: рядки Unicode. Юнікод використовує 16-розрядні числа для представлення символів замість 8-розрядних чисел, які використовуються в ASCII, тобто підтримується 65 536 різних символів.

Остаточний інтерфейс для підтримки Unicode був досягнутий під час незліченних, часто бурхливих дискусій у списку розсилки python-dev, і здебільшого реалізований Марком-Андре Лембургом на основі реалізації рядкового типу Unicode Фредріком Лундом. Детальне пояснення інтерфейсу було написано як PEP 100, «Інтеграція Python Unicode». Ця стаття лише охопить найважливіші моменти щодо інтерфейсів Unicode.

У вихідному коді Python рядки Unicode записуються як u"рядок. Довільні символи Юнікоду можна записувати за допомогою нової керуючої послідовності \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 — звичайний рядок із 1 символу або Unicode, повертає номер символу як ціле число.

  • 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') повертає 2-символьний рядок „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 і повертає 2-кортеж (рядок, довжина). рядок — це 8-бітовий рядок, що містить частину (можливо, весь) рядка Юнікод, перетвореного в дане кодування, а довжина вказує вам, яку частину рядка Юнікод було перетворено.

  • decode_func є протилежністю encode_func, беручи 8-бітний рядок і повертаючи 2-кортеж (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.

Розуміння списку

Списки є основним типом даних у Python, і багато програм маніпулюють списком у певний момент. Дві поширені операції зі списками полягають у проходженні по ним і або виборі елементів, які відповідають певному критерію, або застосуванні певної функції до кожного елемента. Наприклад, маючи список рядків, ви можете вилучити всі рядки, що містять даний підрядок, або видалити кінцеві пробіли з кожного рядка.

Існуючі функції map() і filter() можна використовувати для цієї мети, але вони потребують функції як один із своїх аргументів. Це добре, якщо існує вбудована функція, яку можна передати напряму, але якщо її немає, вам доведеться створити невелику функцію для виконання необхідної роботи, а правила визначення області Python роблять результат негарним, якщо маленька функція потребує Додаткова інформація. Розглянемо перший приклад із попереднього абзацу, знайшовши всі рядки у списку, що містить заданий підрядок. Щоб це зробити, ви можете написати наступне:

# Given the list L, make a list of all strings
# containing the substring 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 ]

Речення forin містять послідовності, які потрібно повторити. Послідовності не обов’язково мають бути однакової довжини, тому що вони не повторюються паралельно, а зліва направо; це більш чітко пояснюється в наступних параграфах. Елементи згенерованого списку будуть послідовними значеннями виразу. Останній пункт if необов’язковий; якщо присутнє, вираз обчислюється та додається до результату, лише якщо умова істинна.

Щоб зробити семантику дуже зрозумілою, розуміння списку еквівалентно наступному коду Python:

for expr1 in sequence1:
    for expr2 in sequence2:
    ...
        for exprN in sequenceN:
             if (condition):
                  # Append the value of
                  # the expression to the
                  # resulting list.

Це означає, що коли є кілька пропозицій forin, результуючий список дорівнюватиме добутку довжин усіх послідовностей. Якщо у вас є два списки довжиною 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, якщо вираз створює кортеж, його потрібно взяти в дужки. Перше розуміння списку нижче є синтаксичною помилкою, тоді як друге є правильним:

# Syntax error
[ x,y for x in seq1 for y in seq2]
# Correct
[ (x,y) for x in seq1 for y in seq2]

Ідея розуміння списків спочатку походить від функціональної мови програмування Haskell (https://www.haskell.org). Ґреґ Юінг найбільш ефективно доводив доцільність додавання їх до Python і написав початковий патч для розуміння списку, який потім, здавалося, нескінченний час обговорювався в списку розсилки python-dev і постійно оновлювався Скіпом Монтанаро.

Доповнене завдання

До 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, який зазвичай був інтерфейсом для модуля strop, написаного мовою C. Додавання 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).

Збирання сміття циклів

Реалізація Python на C використовує підрахунок посилань для реалізації збирання сміття. Кожен об’єкт Python підтримує підрахунок кількості посилань, що вказують на нього самого, і коригує кількість у міру створення чи знищення посилань. Коли кількість посилань досягає нуля, об’єкт більше не доступний, оскільки для доступу до нього потрібно мати посилання на об’єкт, і якщо кількість посилань дорівнює нулю, посилань більше не існує.

Підрахунок посилань має деякі приємні властивості: його легко зрозуміти та реалізувати, а результуюча реалізація є портативною, досить швидкою та добре реагує на інші бібліотеки, які реалізують власні схеми обробки пам’яті. Основна проблема з підрахунком посилань полягає в тому, що він іноді не усвідомлює, що об’єкти більше не доступні, що призводить до витоку пам’яті. Це відбувається, коли є цикли посилань.

Розглянемо найпростіший можливий цикл, екземпляр класу, який має посилання на самого себе:

instance = SomeClass()
instance.myself = instance

Після виконання двох вищезазначених рядків коду кількість посилань примірника дорівнює 2; одне посилання походить від змінної з назвою 'instance', а інше — від атрибута mysel екземпляра.

Що станеться, якщо наступним рядком коду є del instance? Кількість посилань примірника зменшено на 1, тому він має кількість посилань 1; посилання в атрибуті mysel все ще існує. Проте екземпляр більше не доступний через код Python, і його можна видалити. Кілька об’єктів можуть брати участь у циклі, якщо вони мають посилання один на одного, що спричиняє витік усіх об’єктів.

Python 2.0 вирішує цю проблему, періодично виконуючи алгоритм виявлення циклу, який шукає недоступні цикли та видаляє залучені об’єкти. Новий модуль gc надає функції для збирання сміття, отримання статистики налагодження та налаштування параметрів збирача.

Виконання алгоритму виявлення циклу займає деякий час, а тому призведе до додаткових витрат. Сподіваємося, що після того, як ми отримаємо досвід роботи зі збором циклів від використання 2.0, Python 2.1 зможе мінімізувати накладні витрати завдяки ретельному налаштуванню. Поки що неочевидно, скільки продуктивності втрачається, тому що це порівняльний аналіз є складним і дуже залежить від того, як часто програма створює та знищує об’єкти. Виявлення циклів можна вимкнути під час компіляції Python, якщо ви не можете дозволити собі навіть незначне зниження швидкості або підозрюєте, що збирання циклів є помилковим, вказавши перемикач --without-cycle-gc, коли виконання сценарію configure.

Кілька людей взялися за цю проблему та зробили свій внесок у її вирішення. Рання реалізація підходу виявлення циклу була написана Тобі Келсі. Поточний алгоритм був запропонований Еріком Тідеманном під час візиту до CNRI, а Гвідо ван Россум і Ніл Шеменауер написали дві різні реалізації, які пізніше були інтегровані Нілом. Багато інших людей пропонували пропозиції на цьому шляху; архіви списку розсилки python-dev за березень 2000 року містять більшість відповідних обговорень, особливо в темах під назвою «Колекція довідкового циклу для Python» і «Знову завершення».

Інші основні зміни

У синтаксис і вбудовані функції Python внесено різні незначні зміни. Жодна зі змін не є дуже далекосяжною, але це зручні зручності.

Незначні зміни мови

Новий синтаксис робить більш зручним виклик певної функції за допомогою кортежу аргументів та/або словника ключових аргументів. У Python 1.5 і раніших версіях ви використовували вбудовану функцію apply(): apply(f, args, kw) викликає функцію f() з кортежем аргументів args і ключові аргументи в словнику kw. apply() те саме у версії 2.0, але завдяки патчу від Грега Юінга, f(*args, **kw) є коротшим і зрозумілішим способом досягнення того самого ефекту. Цей синтаксис симетричний до синтаксису для визначення функцій:

def f(*args, **kw):
    # args is a tuple of positional args,
    # kw is a dictionary of keyword args
    ...

Оператор print тепер може мати вихід, спрямований на файлоподібний об’єкт, слідуючи за print >> file, подібно до оператора перенаправлення в оболонках Unix. Раніше вам потрібно було використовувати метод write() файлоподібного об’єкта, якому бракує зручності та простоти print, або ви могли призначити нове значення sys.stdout, а потім відновіть старе значення. Для надсилання виводу до стандартної помилки набагато простіше написати це:

print >> sys.stderr, "Warning: action field not supplied"

Модулі тепер можна перейменовувати під час їх імпорту, використовуючи синтаксис імпортувати модуль як ім’я або з імені імпорту модуля як інше ім’я. Патч надіслав Томас Воутерс.

Новий стиль формату доступний при використанні оператора %; „%r“ вставить repr() свого аргументу. Це також було додано з міркувань симетрії, цього разу для симетрії з існуючим стилем формату „%s“, який вставляє str() свого аргументу. Наприклад, '%r %s' % ('abc', 'abc') повертає рядок, що містить 'abc' abc.

Раніше не було можливості реалізувати клас, який замінює вбудований оператор Python in і реалізовує спеціальну версію. obj in seq повертає істину, якщо obj присутній у послідовності seq; Python обчислює це, просто пробуючи кожен індекс послідовності, поки не буде знайдено obj або не буде виявлено IndexError. Moshe Zadka вніс патч, який додає магічний метод __contains__() для надання спеціальної реалізації для in. Крім того, нові вбудовані об’єкти, написані мовою C, можуть визначати, що для них означає in через новий слот у протоколі послідовності.

Попередні версії Python використовували рекурсивний алгоритм для видалення об’єктів. Глибоко вкладені структури даних можуть спричинити заповнення стека C і збій інтерпретатора; Крістіан Тісмер переписав логіку видалення, щоб вирішити цю проблему. У зв’язку з цим, порівняння рекурсивних об’єктів нескінченно рекурсувало і вийшло з ладу; Джеремі Гілтон переписав код, щоб він більше не виходив з ладу, натомість створюючи корисний результат. Наприклад, після цього коду:

a = []
b = []
a.append(a)
b.append(b)

Порівняння a==b повертає true, оскільки дві рекурсивні структури даних є ізоморфними. Дивіться тему «trashcan and PR#7» в архівах списку розсилки python-dev за квітень 2000 року для обговорення, що призвело до цієї реалізації, а також деякі корисні відповідні посилання. Зауважте, що порівняння тепер також можуть створювати винятки. У попередніх версіях Python операція порівняння, наприклад cmp(a,b), завжди давала відповідь, навіть якщо визначений користувачем метод __cmp__() виявив помилку, оскільки результуючий виняток просто мовчки проковтнути.

Work has been done on porting Python to 64-bit Windows on the Itanium processor, mostly by Trent Mick of ActiveState. (Confusingly, sys.platform is still 'win32' on Win64 because it seems that for ease of porting, MS Visual C++ treats code as 32 bit on Itanium.) PythonWin also supports Windows CE; see the Python CE page at http://pythonce.sourceforge.net/ for more information.

Ще одна нова платформа — 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 має неправильний відступ.

Зміни вбудованих функцій

Додано нову вбудовану функцію 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 з повідомленням «неможливо перетворити не рядок із явною базою».

До модуля sys додано нову змінну, що містить більш детальну інформацію про версію. sys.version_info — це кортеж (major, minor, micro, level, serial). Наприклад, у гіпотетичній версії 2.0.1beta1, sys.version_info буде (2, 0 , 1, 'бета', 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

Нові випуски Python намагаються бути сумісними з попередніми випусками, і результати були досить хорошими. Однак деякі зміни вважаються досить корисними, зазвичай тому, що вони виправляють початкові дизайнерські рішення, які виявилися активно помилковими, тому порушення зворотної сумісності не завжди можна уникнути. У цьому розділі перераховано зміни в Python 2.0, які можуть призвести до поломки старого коду Python.

Зміна, яка, ймовірно, найбільше порушить код, полягає в посиленні аргументів, прийнятих деякими методами. Деякі методи приймають кілька аргументів і розглядають їх як кортеж, зокрема різні методи списку, такі як append() і insert(). У попередніх версіях Python, якщо L є списком, L.append( 1,2 ) додає кортеж (1,2) до списку. У Python 2.0 це викликає виняток TypeError із повідомленням: «додавання вимагає рівно 1 аргументу; 2 дано“. Виправлення полягає в тому, щоб просто додати додатковий набір дужок, щоб передати обидва значення як кортеж: 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 мають більш зрозуміле повідомлення про помилку, текст якого буде приблизно таким, як «Екземпляр спаму» не має атрибута «яйця» або «назва «яйця» є не визначено``. Раніше повідомленням про помилку було лише відсутнє ім’я атрибута яйця, і код, написаний для використання цього факту, зламається у 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, написаний Баррі Варшау та Фредріком Лундом.

Розширення/вбудовування змін

Деякі зміни знаходяться під обкладинками, і вони будуть очевидні лише для людей, які пишуть модулі розширення C або вбудовують інтерпретатор Python у більшу програму. Якщо ви не маєте справу з API C Python, можете сміливо пропустити цей розділ.

Номер версії Python C API було збільшено, тому розширення C, скомпільовані для 1.5.2, потрібно перекомпілювати, щоб працювати з 2.0. У Windows Python 2.0 не може імпортувати стороннє розширення, створене для Python 1.5.x, через те, як працюють бібліотеки DLL Windows, тому Python викличе виняток, і імпорт не вдасться.

Користувачі модуля ExtensionClass Джима Фултона будуть раді дізнатися, що були додані хуки, завдяки чому ExtensionClasses тепер підтримуються isinstance() і issubclass(). Це означає, що вам більше не потрібно пам’ятати про написання такого коду, як if type(obj) == myExtensionClass, а можна використовувати більш природний if isinstance(obj, myExtensionClass).

Файл Python/importdl.c, який являв собою масу #ifdefs для підтримки динамічного завантаження на багатьох різних платформах, був очищений і реорганізований Грегом Стайном. importdl.c тепер досить малий, і специфічний для платформи код було переміщено до групи файлів Python/dynload_*.c. Ще одне очищення: у каталозі Include/ також було кілька файлів my*.h, які містили різноманітні хаки для перенесення; їх об’єднано в один файл Include/pyport.h.

Vladimir Marangozov’s long-awaited malloc restructuring was completed, to make it easy to have the Python interpreter use a custom allocator instead of C’s standard malloc(). For documentation, read the comments in Include/pymem.h and Include/objimpl.h. For the lengthy discussions during which the interface was hammered out, see the Web archives of the „patches“ and „python-dev“ lists at python.org.

Останні версії середовища розробки GUSI для MacOS підтримують потоки POSIX. Таким чином, підтримка потоків Python POSIX тепер працює на 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, стикаються з цим обмеженням. Патч від Charles G. Waldman підвищує ліміт з 2**16 до 2**32.

Додано три нові зручні функції, призначені для додавання констант до словника модуля під час ініціалізації модуля: PyModule_AddObject(), PyModule_AddIntConstant() і PyModule_AddStringConstant(). Кожна з цих функцій приймає об’єкт модуля, рядок C із нульовим символом, що містить ім’я, яке потрібно додати, і третій аргумент для значення, яке буде присвоєно імені. Цей третій аргумент є, відповідно, об’єктом Python, довгим C або рядком C.

Було додано API оболонки для обробників сигналів у стилі Unix. PyOS_getsig() отримує обробник сигналу, а PyOS_setsig() встановить новий обробник.

Distutils: полегшення встановлення модулів

До Python 2.0 встановлення модулів було нудною справою — не було можливості автоматично визначити, де встановлено Python, або які параметри компілятора використовувати для модулів розширення. Авторам програмного забезпечення довелося пройти через важкий ритуал редагування файлів Makefile та конфігураційних файлів, які справді працюють лише в Unix, а Windows і MacOS не підтримуються. Користувачі Python зіткнулися з надзвичайно різними інструкціями встановлення, які відрізнялися між різними пакетами розширень, що робило адміністрування встановлення Python чимось на зразок клопітку.

SIG для розповсюджувальних утиліт, очолюваний Грегом Уордом, створив Distutils, систему, яка значно полегшує встановлення пакетів. Вони утворюють пакет distutils, нову частину стандартної бібліотеки Python. У найкращому випадку інсталяція модуля Python із вихідного коду вимагатиме тих самих кроків: спочатку ви просто маєте на увазі розпакування архіву tarball або 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» і «bdist_wininst» вже були використані для створення дистрибутива RPM і інсталятора Windows для програмного забезпечення відповідно. .

Усе це задокументовано в новому посібнику Розповсюдження модулів Python, який доповнює базовий набір документації Python.

Модулі XML

Python 1.5.2 містив простий аналізатор XML у формі модуля xmllib, наданого Sjoerd Mullender. Починаючи з випуску 1.5.2, два різні інтерфейси для обробки XML стали поширеними: SAX2 (версія 2 Simple API для XML) надає інтерфейс, керований подіями, дещо подібний до xmllib, і DOM (об’єкт документа). Model) надає інтерфейс на основі дерева, перетворюючи XML-документ на дерево вузлів, які можна переглядати та змінювати. Python 2.0 містить інтерфейс SAX2 і скорочений інтерфейс DOM як частину пакета xml. Тут ми дамо короткий огляд цих нових інтерфейсів; зверніться до документації Python або вихідного коду для отримання повної інформації. Python XML SIG також працює над покращенням документації.

Підтримка SAX2

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

# Create a parser object
parser = sax.make_parser()

# Tell it what handler to use
handler = SimpleHandler()
parser.setContentHandler( handler )

# Parse a file!
parser.parse( 'hamlet.xml' )

Для отримання додаткової інформації зверніться до документації Python або XML HOWTO на http://pyxml.sourceforge.net/topics/howto/xml-howto.html.

Підтримка DOM

Об’єктна модель документа – це деревовидне представлення документа XML. Екземпляр Document верхнього рівня є коренем дерева та має єдину дочірню примірник Element верхнього рівня. Цей Element має дочірні вузли, що представляють символьні дані та будь-які піделементи, які можуть мати інших власних дочірніх елементів тощо. Використовуючи DOM, ви можете переглядати отримане дерево будь-яким способом, отримувати доступ до значень елементів і атрибутів, вставляти та видаляти вузли та перетворювати дерево назад у XML.

DOM корисний для модифікації XML-документів, оскільки ви можете створити дерево DOM, змінити його, додавши нові вузли або перевпорядкувавши піддерева, а потім створити новий XML-документ як результат. Ви також можете побудувати дерево DOM вручну та перетворити його на XML, що може бути більш гнучким способом створення виводу XML, ніж просто запис <tag1></tag1> у файл.

Реалізація DOM, включена в Python, знаходиться в модулі xml.dom.minidom. Це спрощена реалізація DOM рівня 1 із підтримкою просторів імен XML. Зручні функції parse() і parseString() надаються для створення дерева DOM:

from xml.dom import minidom
doc = minidom.parse('hamlet.xml')

doc є екземпляром Document. Document, як і всі інші класи DOM, такі як Element і Text, є підкласом базового класу Node. Тому всі вузли в дереві DOM підтримують певні загальні методи, такі як toxml(), який повертає рядок, що містить XML-представлення вузла та його дочірніх елементів. Кожен клас також має власні спеціальні методи; наприклад, екземпляри Element і Document мають метод пошуку всіх дочірніх елементів із вказаною назвою тегу. Продовжуючи попередній 2-рядковий приклад:

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

# Remove the first child
root.removeChild( root.childNodes[0] )

# Move the new first child to the end
root.appendChild( root.childNodes[0] )

# Insert the new first child (originally,
# the third child) before the 20th child.
root.insertBefore( root.childNodes[0], root.childNodes[20] )

Знову ж таки, я відсилаю вас до документації Python, щоб отримати повний перелік різних класів Node та їхніх різних методів.

Відношення до PyXML

The XML Special Interest Group has been working on XML-related Python code for a while. Its code distribution, called PyXML, is available from the SIG’s Web pages at https://www.python.org/community/sigs/current/xml-sig. The PyXML distribution also used the package name xml. If you’ve written programs that used PyXML, you’re probably wondering about its compatibility with the 2.0 xml package.

Відповідь полягає в тому, що пакет xml Python 2.0 несумісний з PyXML, але його можна зробити сумісним, встановивши останню версію PyXML. Багато програм можуть обійтися підтримкою XML, яка включена в Python 2.0, але складніші програми вимагають інсталяції повного пакета PyXML. Після встановлення PyXML версії 0.6.0 або новішої замінить пакет xml, який постачається разом із Python, і стане строгим доповненням до стандартного пакета, додаючи купу додаткових функцій. Деякі з додаткових функцій у PyXML включають:

  • 4DOM, повна реалізація DOM від FourThought, Inc.

  • Парсер перевірки xmlproc, написаний Ларсом Маріусом Гаршолом.

  • Модуль прискорювача парсера sgmlop, написаний Фредріком Лундом.

Зміни модуля

Було зроблено багато покращень і виправлень помилок у великій стандартній бібліотеці Python; деякі з постраждалих модулів включають readline, ConfigParser, cgi, calendar, posix, readline, xmllib, aifc, chunk, wave, random, shelve і nntplib. Зверніться до журналів CVS для отримання точних деталей кожного патча.

Брайан Галлью надав підтримку OpenSSL для модуля socket. OpenSSL — це реалізація рівня захищених сокетів, який шифрує дані, що надсилаються через сокет. Під час компіляції 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, таких як колір, підтримка альтернативного набору символів, підтримка панелей і миші. Це означає, що модуль більше не сумісний з операційними системами, які мають лише прокляття BSD, але, здається, на даний момент немає жодної ОС, яка підпадає під цю категорію.

Як згадувалося в попередньому обговоренні підтримки Unicode 2.0, базову реалізацію регулярних виразів, які надає модуль re, було змінено. SRE, нова система регулярних виразів, написана Фредріком Лундом і частково фінансована Hewlett Packard, підтримує зіставлення як з 8-бітними рядками, так і з рядками Unicode.

Нові модулі

Додано ряд нових модулів. Ми просто перерахуємо їх із короткими описами; зверніться до документації 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: інтерфейс для аналізатора Expat XML. (Надав Пол Прескод.)

  • robotparser: Parse a robots.txt file, which is used for writing Web spiders that politely avoid certain areas of a Web site. The parser accepts the contents of a robots.txt file, builds a set of rules from it, and can then answer questions about the fetchability of a given URL. (Contributed by Skip Montanaro.)

  • tabnanny: Модуль/скрипт для перевірки вихідного коду Python на неоднозначні відступи. (Надав Тім Пітерс.)

  • 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) (надано Джеймсом К. Алстромом.)

  • imputil: модуль, який забезпечує простіший спосіб написання налаштованих хуків імпорту порівняно з існуючим модулем ihooks. (Реалізовано Грегом Стайном, з великим обговоренням python-dev на цьому шляху.)

Покращення IDLE

IDLE — це офіційна кросплатформна IDE Python, написана за допомогою Tkinter. Python 2.0 містить IDLE 0.6, який додає низку нових функцій і покращень. Неповний список:

  • Покращення та оптимізація інтерфейсу користувача, особливо в області підсвічування синтаксису та автоматичного відступу.

  • Переглядач класів тепер показує більше інформації, наприклад функції верхнього рівня в модулі.

  • Ширина вкладки тепер доступна користувачеві. Під час відкриття існуючого файлу Python IDLE автоматично визначає правила відступів і адаптує їх.

  • Тепер існує підтримка виклику браузерів на різних платформах, які використовуються для відкриття документації Python у браузері.

  • У IDLE тепер є командний рядок, який багато в чому схожий на ванільний інтерпретатор Python.

  • У багатьох місцях додано підказки щодо дзвінків.

  • IDLE тепер можна встановити як пакет.

  • Тепер у вікні редактора внизу є рядок/стовпець.

  • Три нові команди натискання клавіш: перевірити модуль (Alt-F5), імпортувати модуль (F5) і запустити сценарій (Ctrl-F5).

Видалені та застарілі модулі

Кілька модулів було вилучено, оскільки вони застаріли, або тому, що тепер є кращі способи зробити те саме. Модуль stdwin зник; це було для незалежного від платформи інструментарію вікон, який більше не розробляється.

Кілька модулів переміщено до підкаталогу lib-old: cmp, cmpcache, dircmp, dump, find, grep, packmail, poly, util, whatsound, zmod. Якщо у вас є код, який покладається на модуль, який було переміщено до lib-old, ви можете просто додати цей каталог до sys.path, щоб отримати їх назад, але вам рекомендується оновити будь-який код який використовує ці модулі.

Подяки

Автори хотіли б подякувати наступним людям за пропозиції щодо різних чернеток цієї статті: Девід Болен, Марк Хаммонд, Грег Хаузер, Джеремі Гілтон, Фредрік Лунд, Детлеф Ланнерт, Ааз Марух, Скіп Монтанаро, Володимир Марангозов, Тобіас Ползін, Гвідо ван Россум, Ніл Шеменауер і Расс Шмідт.