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

2.3.md

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

1> **Источник:** https://python-all.ru/3.2/whatsnew/2.3.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Что нового в Python 2.389| Автор: | A.M. Kuchling |10| --- | --- |1112В этой статье описываются новые возможности Python 2.3. Python 2.3 был выпущен 29 июля 2003 года.1314Основные темы Python 2.3 – это шлифовка некоторых возможностей, добавленных в 2.2, добавление различных мелких, но полезных улучшений в ядро языка и расширение стандартной библиотеки. Новая объектная модель, представленная в предыдущей версии, выиграла от 18 месяцев исправлений ошибок и оптимизационных усилий, которые повысили производительность классов нового стиля. Было добавлено несколько новых встроенных функций, таких как [`sum()`](https://python-all.ru/3.2/library/functions.html#sum) и [`enumerate()`](https://python-all.ru/3.2/library/functions.html#enumerate). Оператор [`in`](https://python-all.ru/3.2/reference/expressions.html#in) теперь можно использовать для поиска подстрок (например, `"ab" in "abc"` возвращает [`True`](https://python-all.ru/3.2/library/constants.html#True)).1516Некоторые из множества новых возможностей библиотеки включают логические типы, множества, кучи и типы даты/времени, возможность импортировать модули из ZIP-архивов, поддержку метаданных для долгожданного каталога Python, обновленную версию IDLE, а также модули для журналирования сообщений, переноса текста, разбора CSV-файлов, обработки параметров командной строки, использования баз данных BerkeleyDB... список новых и улучшенных модулей обширен.1718Эта статья не пытается дать полную спецификацию новых возможностей, а предоставляет удобный обзор. За полными подробностями следует обращаться к документации по Python 2.3, такой как «Справочник по библиотеке Python» и «Руководство по языку Python». Чтобы понять полную реализацию и обоснование дизайна, следует обратиться к PEP для конкретной новой возможности.1920## PEP 218: Стандартный тип данных «множество»2122Новый модуль `sets` содержит реализацию типа данных «множество». Класс `Set` предназначен для изменяемых множеств, в которые можно добавлять и удалять элементы. Класс `ImmutableSet` – для неизменяемых множеств, и экземпляры `ImmutableSet` поэтому могут использоваться в качестве ключей словаря. Множества построены поверх словарей, поэтому элементы множества должны быть хешируемыми.2324Вот простой пример:2526```python27>>> import sets28>>> S = sets.Set([1,2,3])29>>> S30Set([1, 2, 3])31>>> 1 in S32True33>>> 0 in S34False35>>> S.add(5)36>>> S.remove(3)37>>> S38Set([1, 2, 5])39>>>40```4142Объединение и пересечение множеств можно вычислить с помощью методов `union()` и `intersection()`; альтернативная запись использует побитовые операторы `&` и `|`. Изменяемые множества также имеют версии этих методов, изменяющие само множество: `union_update()` и `intersection_update()`.4344```python45>>> S1 = sets.Set([1,2,3])46>>> S2 = sets.Set([4,5,6])47>>> S1.union(S2)48Set([1, 2, 3, 4, 5, 6])49>>> S1 | S2                  # Альтернативная запись50Set([1, 2, 3, 4, 5, 6])51>>> S1.intersection(S2)52Set([])53>>> S1 & S2                  # Альтернативная запись54Set([])55>>> S1.union_update(S2)56>>> S157Set([1, 2, 3, 4, 5, 6])58>>>59```6061Также можно вычислить симметрическую разность двух множеств. Это множество всех элементов объединения, которые не входят в пересечение. Другими словами, симметрическая разность содержит все элементы, которые находятся ровно в одном из множеств. Опять же, есть альтернативная запись (`^`) и версия, изменяющая само множество, с неуклюжим именем `symmetric_difference_update()`.6263```python64>>> S1 = sets.Set([1,2,3,4])65>>> S2 = sets.Set([3,4,5,6])66>>> S1.symmetric_difference(S2)67Set([1, 2, 5, 6])68>>> S1 ^ S269Set([1, 2, 5, 6])70>>>71```7273Также есть методы `issubset()` и `issuperset()` для проверки, является ли одно множество подмножеством или надмножеством другого:7475```python76>>> S1 = sets.Set([1,2,3])77>>> S2 = sets.Set([2,3])78>>> S2.issubset(S1)79True80>>> S1.issubset(S2)81False82>>> S1.issuperset(S2)83True84>>>85```8687> **См. также**88>89> **[**PEP 218**](https://python-all.ru/3.2/whatsnew/2.3.html) – Добавление встроенного типа объектов-множеств**90>91> PEP написан Грегом В. Уилсоном. Реализован Грегом В. Уилсоном, Алексом Мартелли и GvR.9293## PEP 255: Простые генераторы9495В Python 2.2 генераторы были добавлены как опциональная возможность, включаемая директивой `from __future__ import generators`. В версии 2.3 генераторы больше не нужно специально включать, они теперь присутствуют всегда; это означает, что [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield) теперь всегда является ключевым словом. Остальная часть этого раздела – копия описания генераторов из документа «What’s New in Python 2.2»; если вы читали его, когда выходил Python 2.2, можете пропустить остаток этого раздела.9697Вам, несомненно, знакомо, как работают вызовы функций в Python или C. Когда вы вызываете функцию, она получает отдельное пространство имён, в котором создаются её локальные переменные. Когда функция достигает оператора [`return`](https://python-all.ru/3.2/reference/simple_stmts.html#return), локальные переменные уничтожаются, а полученное значение возвращается вызывающему коду. Последующий вызов той же функции получит новый набор локальных переменных. Но что, если бы локальные переменные не отбрасывались при выходе из функции? Что, если бы можно было возобновить выполнение функции с того места, где она остановилась? Именно это и предоставляют генераторы; их можно рассматривать как возобновляемые функции.9899Вот простейший пример функции-генератора:100101```python102def generate_ints(N):103    for i in range(N):104        yield i105```106107Для генераторов было введено новое ключевое слово [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield). Любая функция, содержащая оператор [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield), является генераторной функцией; это обнаруживается компилятором байт-кода Python, который соответственно компилирует такую функцию особым образом.108109Когда вы вызываете генераторную функцию, она возвращает не одно значение; вместо этого она возвращает объект-генератор, поддерживающий протокол итератора. При выполнении оператора [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield) генератор выводит значение `i`, аналогично оператору [`return`](https://python-all.ru/3.2/reference/simple_stmts.html#return). Большое различие между [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield) и оператором [`return`](https://python-all.ru/3.2/reference/simple_stmts.html#return) состоит в том, что при достижении [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield) состояние выполнения генератора приостанавливается, а локальные переменные сохраняются. При следующем вызове метода `.next()` генератора функция продолжит выполнение сразу после оператора [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield). (По сложным причинам оператор [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield) не допускается внутри блока [`try`](https://python-all.ru/3.2/reference/compound_stmts.html#try) оператора [`try`](https://python-all.ru/3.2/reference/compound_stmts.html#try)...[`finally`](https://python-all.ru/3.2/reference/compound_stmts.html#finally); прочитайте [**PEP 255**](https://python-all.ru/3.2/whatsnew/2.3.html) для полного объяснения взаимодействия между [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield) и исключениями.)110111Вот пример использования генератора `generate_ints()`:112113```python114>>> gen = generate_ints(3)115>>> gen116<generator object at 0x8117f90>117>>> gen.next()1180119>>> gen.next()1201121>>> gen.next()1222123>>> gen.next()124Traceback (most recent call last):125  File "stdin", line 1, in ?126  File "stdin", line 2, in generate_ints127StopIteration128```129130Можно также написать `for i in generate_ints(5)`, или `a,b,c = generate_ints(3)`.131132Внутри генераторной функции оператор [`return`](https://python-all.ru/3.2/reference/simple_stmts.html#return) может использоваться только без значения и сигнализирует об окончании выдачи значений; после этого генератор не может вернуть больше значений. [`return`](https://python-all.ru/3.2/reference/simple_stmts.html#return) со значением, например `return 5`, является синтаксической ошибкой внутри генераторной функции. Окончание результатов генератора также можно указать, возбудив [`StopIteration`](https://python-all.ru/3.2/library/exceptions.html#StopIteration) вручную или просто позволив потоку выполнения достичь конца функции.133134Эффекта генераторов можно добиться вручную, написав собственный класс и сохранив все локальные переменные генератора как атрибуты экземпляра. Например, возврат списка целых чисел можно сделать, установив `self.count` в 0 и заставив метод [`next()`](https://python-all.ru/3.2/library/functions.html#next) увеличивать `self.count` и возвращать его. Однако для сколько-нибудь сложного генератора написание соответствующего класса было бы гораздо запутаннее. `Lib/test/test_generators.py` содержит ряд более интересных примеров. Простейший из них реализует обход дерева в порядке (in-order) с использованием генераторов рекурсивно.135136```python137# Рекурсивный генератор, порождающий листья дерева в порядке in-order.138def inorder(t):139    if t:140        for x in inorder(t.left):141            yield x142        yield t.label143        for x in inorder(t.right):144            yield x145```146147Два других примера в `Lib/test/test_generators.py` дают решения задачи о N ферзях (размещение $N$ ферзей на доске $N \\times N$ так, чтобы ни один ферзь не угрожал другому) и задачи о ходе коня (маршрут, который проводит коня через каждую клетку доски $N \\times N$, не посещая ни одну клетку дважды).148149Идея генераторов пришла из других языков программирования, особенно Icon ([http://www.cs.arizona.edu/icon/](https://python-all.ru/3.2/whatsnew/2.3.html)), где идея генераторов является центральной. В Icon каждое выражение и вызов функции ведут себя как генератор. Один пример из «An Overview of the Icon Programming Language» по адресу [http://www.cs.arizona.edu/icon/docs/ipd266.htm](https://python-all.ru/3.2/whatsnew/2.3.html) даёт представление о том, как это выглядит:150151```python152sentence := "Store it in the neighboring harbor"153if (i := find("or", sentence)) > 5 then write(i)154```155156В Icon функция `find()` возвращает индексы, по которым встречается подстрока «or»: 3, 23, 33. В операторе [`if`](https://python-all.ru/3.2/reference/compound_stmts.html#if) `i` сначала присваивается значение 3, но 3 меньше 5, поэтому сравнение не проходит, и Icon повторяет его со вторым значением 23. 23 больше 5, поэтому сравнение теперь успешно, и код выводит значение 23 на экран.157158Python не заходит так далеко, как Icon, в принятии генераторов в качестве центральной концепции. Генераторы считаются частью ядра языка Python, но их изучение или использование не является обязательным; если они не решают никаких проблем, их можно смело игнорировать. Одна новая особенность интерфейса Python по сравнению с Icon заключается в том, что состояние генератора представлено в виде конкретного объекта (итератора), который можно передавать другим функциям или хранить в структуре данных.159160> **См. также**161>162> **[**PEP 255**](https://python-all.ru/3.2/whatsnew/2.3.html) - Simple Generators**163>164> Авторы: Нил Шеменауэр, Тим Питерс, Магнус Ли Хетланд. Реализовано в основном Нилом Шеменауэром и Тимом Питерсом, с дополнительными исправлениями от команды Python Labs.165166## PEP 263: Кодировки исходного кода167168Файлы исходного кода Python теперь можно объявлять как файлы в различных кодировках символов. Кодировки объявляются путём включения специально отформатированного комментария в первую или вторую строку исходного файла. Например, файл в UTF-8 можно объявить с помощью:169170```python171#!/usr/bin/env python172# -*- coding: UTF-8 -*-173```174175Без такого объявления кодировки по умолчанию используется 7-битная ASCII. Выполнение или импорт модулей, которые содержат строковые литералы с 8-битными символами и не имеют объявления кодировки, приведёт к тому, что Python 2.3 сгенерирует [`DeprecationWarning`](https://python-all.ru/3.2/library/exceptions.html#DeprecationWarning); в версии 2.4 это будет синтаксической ошибкой.176177Объявление кодировки влияет только на строковые литералы Unicode, которые будут преобразованы в Unicode с использованием указанной кодировки. Обратите внимание, что идентификаторы Python по-прежнему ограничены символами ASCII, поэтому нельзя использовать имена переменных, содержащие символы за пределами обычных буквенно-цифровых.178179> **См. также**180>181> **[**PEP 263**](https://python-all.ru/3.2/whatsnew/2.3.html) – Определение кодировок исходного кода Python**182>183> Авторы: Marc-André Lemburg и Martin von Löwis; реализовано Suzuki Hisao и Martin von Löwis.184185## PEP 273: Импорт модулей из ZIP-архивов186187Новый модуль [`zipimport`](https://python-all.ru/3.2/library/zipimport.html#module-zipimport) добавляет поддержку импорта модулей из ZIP-архивов. Явно импортировать этот модуль не нужно; он будет импортирован автоматически, если имя ZIP-архива добавлено в `sys.path`. Например:188189```python190amk@nyman:~/src/python$ unzip -l /tmp/example.zip191Archive:  /tmp/example.zip192  Length     Date   Time    Name193 --------    ----   ----    ----194     8467  11-26-02 22:30   jwzthreading.py195 --------                   -------196     8467                   1 file197amk@nyman:~/src/python$ ./python198Python 2.3 (#1, Aug 1 2003, 19:54:32)199>>> import sys200>>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path201>>> import jwzthreading202>>> jwzthreading.__file__203'/tmp/example.zip/jwzthreading.py'204>>>205```206207Запись в `sys.path` теперь может быть именем ZIP-архива. ZIP-архив может содержать файлы любого типа, но импортировать можно только файлы с именами `*.py`, `*.pyc` или `*.pyo`. Если архив содержит только файлы `*.py`, Python не будет пытаться изменить архив, добавляя соответствующий файл `*.pyc`; это означает, что если ZIP-архив не содержит файлов `*.pyc`, импорт может быть довольно медленным.208209Также можно указать путь внутри архива, чтобы импортировать только из подкаталога; например, путь `/tmp/example.zip/lib/` будет импортировать только из подкаталога `lib/` внутри архива.210211> **См. также**212>213> **[**PEP 273**](https://python-all.ru/3.2/whatsnew/2.3.html) – Импорт модулей из Zip-архивов**214>215> Автор: James C. Ahlstrom, он же предоставил реализацию. Python 2.3 следует спецификации из216>217> [**PEP 273**](https://python-all.ru/3.2/whatsnew/2.3.html)218>219> , но использует реализацию, написанную Just van Rossum, которая применяет хуки импорта, описанные в220>221> [**PEP 302**](https://python-all.ru/3.2/whatsnew/2.3.html)222>223> . См. раздел224>225> [*PEP 302: Новые хуки импорта*](https://python-all.ru/3.2/whatsnew/2.3.html#section-pep302)226>227> для описания новых хуков импорта.228229## PEP 277: Поддержка имен файлов в Unicode для Windows NT230231В Windows NT, 2000 и XP система хранит имена файлов в виде строк Unicode. Традиционно Python представлял имена файлов как байтовые строки, что неудовлетворительно, так как делает некоторые имена файлов недоступными.232233Python теперь позволяет использовать произвольные строки Unicode (в пределах ограничений файловой системы) для всех функций, ожидающих имена файлов, прежде всего для встроенной функции [`open()`](https://python-all.ru/3.2/library/functions.html#open). Если строку Unicode передать в [`os.listdir()`](https://python-all.ru/3.2/library/os.html#os.listdir), Python теперь возвращает список строк Unicode. Новая функция `os.getcwdu()` возвращает текущий каталог в виде строки Unicode.234235Байтовые строки по-прежнему работают как имена файлов, и в Windows Python будет прозрачно преобразовывать их в Unicode, используя кодировку `mbcs`.236237Другие системы также допускают строки Unicode в качестве имён файлов, но преобразуют их в байтовые строки перед передачей системе, что может вызвать [`UnicodeError`](https://python-all.ru/3.2/library/exceptions.html#UnicodeError). Приложения могут проверить, поддерживаются ли произвольные строки Unicode в качестве имён файлов, проверив [`os.path.supports_unicode_filenames`](https://python-all.ru/3.2/library/os.path.html#os.path.supports_unicode_filenames) – логическое значение.238239В MacOS [`os.listdir()`](https://python-all.ru/3.2/library/os.html#os.listdir) теперь может возвращать имена файлов в Unicode.240241> **См. также**242>243> **[**PEP 277**](https://python-all.ru/3.2/whatsnew/2.3.html) – Поддержка имен файлов в Unicode для Windows NT**244>245> Автор: Neil Hodgson; реализовано Neil Hodgson, Martin von Löwis и Mark Hammond.246247## PEP 278: Универсальная поддержка символов новой строки248249Три основные операционные системы, используемые сегодня, – это Microsoft Windows, Macintosh OS от Apple и различные производные Unix. Небольшое раздражение при кроссплатформенной работе заключается в том, что эти три платформы используют разные символы для обозначения концов строк в текстовых файлах. Unix использует перевод строки (символ ASCII 10), MacOS использует возврат каретки (символ ASCII 13), а Windows использует двухсимвольную последовательность: возврат каретки и перевод строки.250251Файловые объекты Python теперь могут поддерживать соглашения об окончании строк, отличные от принятых на платформе, на которой выполняется Python. Открытие файла с режимом `'U'` или `'rU'` откроет файл для чтения в режиме [*универсальных новых строк*](https://python-all.ru/3.2/glossary.html#term-universal-newlines) (universal newlines). Все три соглашения об окончании строк будут преобразованы в `'\n'` в строках, возвращаемых различными файловыми методами, такими как `read()` и [`readline()`](https://python-all.ru/3.2/library/readline.html#module-readline).252253Поддержка универсальных новых строк также используется при импорте модулей и при выполнении файла с помощью функции `execfile()`. Это означает, что модули Python могут распространяться между всеми тремя операционными системами без необходимости преобразовывать окончания строк.254255Эту возможность можно отключить при компиляции Python, указав флаг *--without-universal-newlines* при запуске скрипта **configure**.256257> **См. также**258>259> **[**PEP 278**](https://python-all.ru/3.2/whatsnew/2.3.html) – Универсальная поддержка символов новой строки**260>261> Автор и разработчик: Jack Jansen.262263## PEP 279: enumerate()264265Новая встроенная функция [`enumerate()`](https://python-all.ru/3.2/library/functions.html#enumerate) делает некоторые циклы немного понятнее. `enumerate(thing)`, где *thing* – либо итератор, либо последовательность, возвращает итератор, который возвращает `(0, thing[0])`, `(1, thing[1])`, `(2, thing[2])` и так далее.266267Типичный способ изменить каждый элемент списка выглядит так:268269```python270for i in range(len(L)):271    item = L[i]272    # ... вычислить результат на основе элемента ...273    L[i] = result274```275276Это можно переписать с использованием [`enumerate()`](https://python-all.ru/3.2/library/functions.html#enumerate) следующим образом:277278```python279for i, item in enumerate(L):280    # ... вычислить результат на основе элемента ...281    L[i] = result282```283284> **См. также**285>286> **[**PEP 279**](https://python-all.ru/3.2/whatsnew/2.3.html) – Встроенная функция enumerate()**287>288> Автор и разработчик: Raymond D. Hettinger.289290## PEP 282: Пакет logging291292В Python 2.3 добавлен стандартный пакет для ведения журналов – [`logging`](https://python-all.ru/3.2/library/logging.html#module-logging). Он предоставляет мощный и гибкий механизм для генерации записей журнала, которые затем можно фильтровать и обрабатывать различными способами. Для управления поведением журналирования программы можно использовать файл конфигурации в стандартном формате. Python включает обработчики, которые могут записывать записи журнала в стандартный поток ошибок, в файл или сокет, отправлять их в системный журнал или даже отправлять по электронной почте на определённый адрес; конечно, можно также написать собственные классы обработчиков.293294Класс `Logger` является основным классом. Большая часть прикладного кода будет работать с одним или несколькими объектами `Logger`, каждый из которых используется конкретной подсистемой приложения. Каждый `Logger` идентифицируется именем, и имена организованы в иерархию с использованием `.` в качестве разделителя компонентов. Например, у вас могут быть экземпляры `Logger` с именами `server`, `server.auth` и `server.network`. Последние два экземпляра находятся ниже `server` в иерархии. Это означает, что если вы увеличите подробность для `server` или направите сообщения `server` другому обработчику, изменения также будут применены к записям, регистрируемым для `server.auth` и `server.network`. Существует также корневой `Logger`, который является родителем всех остальных регистраторов.295296Для простых случаев пакет [`logging`](https://python-all.ru/3.2/library/logging.html#module-logging) содержит несколько удобных функций, которые всегда используют корневой логгер:297298```python299import logging300301logging.debug('Debugging information')302logging.info('Informational message')303logging.warning('Warning:config file %s not found', 'server.conf')304logging.error('Error occurred')305logging.critical('Critical error -- shutting down')306```307308Это даёт следующий вывод:309310```python311WARNING:root:Warning:config file server.conf not found312ERROR:root:Error occurred313CRITICAL:root:Critical error -- shutting down314```315316В конфигурации по умолчанию информационные сообщения и сообщения отладки подавляются, а вывод направляется в стандартный поток ошибок. Можно включить отображение информационных и отладочных сообщений, вызвав метод `setLevel()` на корневом логгере.317318Обратите внимание на использование операторов форматирования строк в вызове `warning()`; все функции для записи сообщений в журнал принимают аргументы `(msg, arg1, arg2, ...)` и записывают строку, полученную в результате `msg % (arg1, arg2, ...)`.319320Существует также функция `exception()`, которая записывает самую последнюю traceback. Любая из других функций также запишет traceback, если указать истинное значение для именованного аргумента *exc\_info*.321322```python323def f():324    try:    1/0325    except: logging.exception('Problem recorded')326327f()328```329330Это даёт следующий вывод:331332```python333ERROR:root:Problem recorded334Traceback (most recent call last):335  File "t.py", line 6, in f336    1/0337ZeroDivisionError: integer division or modulo by zero338```339340Немного более сложные программы будут использовать регистратор, отличный от корневого. Функция `getLogger(name)()` используется для получения определённого журнала, создавая его, если он ещё не существует. `getLogger(None)()` возвращает корневой регистратор.341342```python343log = logging.getLogger('server')344 ...345log.info('Listening on port %i', port)346 ...347log.critical('Disk full')348 ...349```350351Записи журнала обычно распространяются вверх по иерархии, поэтому сообщение, записанное в `server.auth`, также видно логгерам `server` и `root`, но `Logger` может предотвратить это, установив своё свойство `propagate` в значение [`False`](https://python-all.ru/3.2/library/constants.html#False).352353Пакет [`logging`](https://python-all.ru/3.2/library/logging.html#module-logging) предоставляет и другие классы, которые можно настраивать. Когда экземпляру `Logger` поступает команда записать сообщение, он создает экземпляр `LogRecord`, который отправляется любому количеству различных экземпляров `Handler`. Логгеры и обработчики также могут иметь присоединенный список фильтров, и каждый фильтр может привести к игнорированию `LogRecord` или может изменить запись перед передачей. При окончательном выводе экземпляры `LogRecord` преобразуются в текст классом `Formatter`. Все эти классы могут быть заменены собственными специально написанными классами.354355Со всеми этими возможностями пакет [`logging`](https://python-all.ru/3.2/library/logging.html#module-logging) должен обеспечивать достаточную гибкость даже для самых сложных приложений. Это лишь неполный обзор его функций; пожалуйста, обратитесь к справочной документации пакета за всеми подробностями. Также полезно прочитать [**PEP 282**](https://python-all.ru/3.2/whatsnew/2.3.html).356357> **См. также**358>359> **[**PEP 282**](https://python-all.ru/3.2/whatsnew/2.3.html) – Система логирования**360>361> Написано Vinay Sajip и Trent Mick; реализовано Vinay Sajip.362363## PEP 285: Логический тип364365Логический тип был добавлен в Python 2.3. В модуль `__builtin__` были добавлены две новые константы, [`True`](https://python-all.ru/3.2/library/constants.html#True) и [`False`](https://python-all.ru/3.2/library/constants.html#False). (Константы [`True`](https://python-all.ru/3.2/library/constants.html#True) и [`False`](https://python-all.ru/3.2/library/constants.html#False) были добавлены во встроенные константы в Python 2.2.1, но версии 2.2.1 просто установлены в целочисленные значения 1 и 0 и не являются отдельным типом.)366367Объект типа для этого нового типа называется [`bool`](https://python-all.ru/3.2/library/functions.html#bool); его конструктор принимает любое значение Python и преобразует его в [`True`](https://python-all.ru/3.2/library/constants.html#True) или [`False`](https://python-all.ru/3.2/library/constants.html#False).368369```python370>>> bool(1)371True372>>> bool(0)373False374>>> bool([])375False376>>> bool( (1,) )377True378```379380Большинство модулей стандартной библиотеки и встроенных функций были изменены, чтобы возвращать логические значения.381382```python383>>> obj = []384>>> hasattr(obj, 'append')385True386>>> isinstance(obj, list)387True388>>> isinstance(obj, tuple)389False390```391392Логический тип Python был добавлен с основной целью сделать код более понятным. Например, читая функцию и встречая оператор `return 1`, можно задаться вопросом, представляет ли `1` логическое значение, индекс или коэффициент, умножающий другую величину. Если же оператор – `return True`, смысл возвращаемого значения совершенно ясен.393394Логический тип Python был *не* добавлен ради строгой проверки типов. Очень строгий язык, такой как Pascal, также запретил бы выполнять арифметические операции с логическими значениями и потребовал бы, чтобы выражение в операторе [`if`](https://python-all.ru/3.2/reference/compound_stmts.html#if) всегда вычислялось до логического результата. Python не настолько строг и никогда не будет, как явно указано в [**PEP 285**](https://python-all.ru/3.2/whatsnew/2.3.html). Это означает, что можно по-прежнему использовать любое выражение в операторе [`if`](https://python-all.ru/3.2/reference/compound_stmts.html#if), даже те, которые вычисляются в список, кортеж или какой-нибудь произвольный объект. Логический тип является подклассом класса [`int`](https://python-all.ru/3.2/library/functions.html#int), так что арифметика с логическими значениями по-прежнему работает.395396```python397>>> True + 13982399>>> False + 14001401>>> False * 754020403>>> True * 7540475405```406407Если резюмировать [`True`](https://python-all.ru/3.2/library/constants.html#True) и [`False`](https://python-all.ru/3.2/library/constants.html#False) одной фразой: это альтернативные способы записи целочисленных значений 1 и 0, с единственным отличием: функции [`str()`](https://python-all.ru/3.2/library/functions.html#str) и [`repr()`](https://python-all.ru/3.2/library/functions.html#repr) возвращают строки `'True'` и `'False'` вместо `'1'` и `'0'`.408409> **См. также**410>411> **[**PEP 285**](https://python-all.ru/3.2/whatsnew/2.3.html) – Добавление логического типа**412>413> Автор и разработчик: GvR.414415## PEP 293: Колбэки обработки ошибок кодеков416417При кодировании строки Unicode в байтовую строку могут встретиться символы, которые невозможно закодировать. До сих пор Python позволял задавать обработку ошибок как «strict» (вызывает [`UnicodeError`](https://python-all.ru/3.2/library/exceptions.html#UnicodeError)), «ignore» (пропускает символ) или «replace» (использует вопросительный знак в выходной строке), при этом «strict» является поведением по умолчанию. Может потребоваться указать альтернативную обработку таких ошибок, например, вставку ссылки на символ XML или ссылки на сущность HTML в преобразованную строку.418419В Python теперь есть гибкая инфраструктура для добавления различных стратегий обработки. Новые обработчики ошибок можно добавить с помощью [`codecs.register_error()`](https://python-all.ru/3.2/library/codecs.html#codecs.register_error), после чего кодек может получить доступ к обработчику ошибок с помощью [`codecs.lookup_error()`](https://python-all.ru/3.2/library/codecs.html#codecs.lookup_error). Для кодеков, написанных на C, был добавлен эквивалентный C API. Обработчик ошибок получает необходимую информацию о состоянии, такую как преобразуемая строка, позиция в строке, где была обнаружена ошибка, и целевая кодировка. Затем обработчик может либо вызвать исключение, либо вернуть строку замены.420421С помощью этой платформы были реализованы два дополнительных обработчика ошибок: «backslashreplace» использует экранирование обратной косой чертой Python для представления незакодируемых символов, а «xmlcharrefreplace» генерирует ссылки на символы XML.422423> **См. также**424>425> **[**PEP 293**](https://python-all.ru/3.2/whatsnew/2.3.html) – Колбэки обработки ошибок кодеков**426>427> Автор и разработчик: Walter Dörwald.428429## PEP 301: Индекс пакетов и метаданные для Distutils430431Поддержка долгожданного каталога Python впервые появляется в версии 2.3.432433Основой каталога является новая команда Distutils **register**. Выполнение `python setup.py register` собирает метаданные пакета: имя, версию, автора, описание и т. д. – и отправляет их на центральный сервер каталога. Полученный каталог доступен по адресу [http://www.python.org/pypi](https://python-all.ru/3.2/whatsnew/2.3.html).434435Чтобы сделать каталог немного более полезным, в функцию `setup()` Distutils был добавлен новый необязательный именованный аргумент *classifiers*. Можно указать список строк в стиле [Trove](https://python-all.ru/3.2/whatsnew/2.3.html), чтобы помочь классифицировать программное обеспечение.436437Вот пример `setup.py` с классификаторами, написанный для совместимости со старыми версиями Distutils:438439```python440from distutils import core441kw = {'name': "Quixote",442      'version': "0.5.1",443      'description': "A highly Pythonic Web application framework",444      # ...445      }446447if (hasattr(core, 'setup_keywords') and448    'classifiers' in core.setup_keywords):449    kw['classifiers'] = \450        ['Topic :: Internet :: WWW/HTTP :: Dynamic Content',451         'Environment :: No Input/Output (Daemon)',452         'Intended Audience :: Developers'],453454core.setup(**kw)455```456457Полный список классификаторов можно получить, выполнив `python setup.py register --list-classifiers`.458459> **См. также**460>461> **[**PEP 301**](https://python-all.ru/3.2/whatsnew/2.3.html) – Индекс пакетов и метаданные для Distutils**462>463> Автор и разработчик: Richard Jones.464465## PEP 302: Новые хуки импорта466467Хотя возможность писать пользовательские хуки импорта существовала с момента появления модуля `ihooks` в Python 1.3, никто не был по-настоящему доволен этим, потому что написание новых хуков импорта – дело сложное и запутанное. Были предложены различные альтернативы, такие как модули `imputil` и `iu`, но ни одна из них не получила широкого признания, и ни одна из них не была легко используемой из кода на C.468469[**PEP 302**](https://python-all.ru/3.2/whatsnew/2.3.html) заимствует идеи у своих предшественников, особенно у модуля Гордона Макмиллана `iu`. В модуль [`sys`](https://python-all.ru/3.2/library/sys.html#module-sys) добавлены три новых элемента:470471- `sys.path_hooks` – это список вызываемых объектов; чаще всего это будут классы. Каждый вызываемый объект принимает строку, содержащую путь, и либо возвращает объект импортера, который будет обрабатывать импорт из этого пути, либо вызывает исключение [`ImportError`](https://python-all.ru/3.2/library/exceptions.html#ImportError), если не может обработать этот путь.472- `sys.path_importer_cache` кеширует объекты импортеров для каждого пути, так что `sys.path_hooks` нужно будет проходить только один раз для каждого пути.473- `sys.meta_path` – это список объектов импортеров, которые будут просматриваться до того, как будет проверен `sys.path`. Этот список изначально пуст, но пользовательский код может добавлять в него объекты. Дополнительные встроенные и замороженные модули могут быть импортированы объектом, добавленным в этот список.474475Объекты-импортёры должны иметь единственный метод `find_module(fullname, path=None)()`. *fullname* – это имя модуля или пакета, например `string` или `distutils.core`. `find_module()` должна возвращать объект-загрузчик, имеющий единственный метод `load_module(fullname)()`, который создаёт и возвращает соответствующий объект модуля.476477Псевдокод новой логики импорта в Python выглядит примерно так (немного упрощён; полные подробности см. в [**PEP 302**](https://python-all.ru/3.2/whatsnew/2.3.html)):478479```python480for mp in sys.meta_path:481    loader = mp(fullname)482    if loader is not None:483        <module> = loader.load_module(fullname)484485for path in sys.path:486    for hook in sys.path_hooks:487        try:488            importer = hook(path)489        except ImportError:490            # ImportError, поэтому попробуем другие перехватчики путей491            pass492        else:493            loader = importer.find_module(fullname)494            <module> = loader.load_module(fullname)495496# Не найдено!497raise ImportError498```499500> **См. также**501>502> **[**PEP 302**](https://python-all.ru/3.2/whatsnew/2.3.html) – новые хуки импорта**503>504> Автор: Just van Rossum и Paul Moore. Реализовано Just van Rossum.505506## PEP 305: Файлы с разделителями-запятыми507508Файлы с разделителями-запятыми – это формат, часто используемый для экспорта данных из баз данных и электронных таблиц. В Python 2.3 добавлен синтаксический анализатор таких файлов.509510Формат с разделителями-запятыми на первый взгляд обманчиво прост:511512```python513Costs,150,200,3.95514```515516Прочитать строку и вызвать `line.split(',')`: что может быть проще? Но добавьте строковые данные, которые могут содержать запятые, и всё становится сложнее:517518```python519"Costs",150,200,3.95,"Includes taxes, shipping, and sundry items"520```521522Большое уродливое регулярное выражение может это разобрать, но использование нового пакета [`csv`](https://python-all.ru/3.2/library/csv.html#module-csv) гораздо проще:523524```python525import csv526527input = open('datafile', 'rb')528reader = csv.reader(input)529for line in reader:530    print line531```532533Функция `reader()` принимает множество различных параметров. Разделитель полей не ограничен запятой и может быть изменен на любой символ, как и символы кавычек и окончания строки.534535Можно определять и регистрировать различные диалекты файлов с разделителями-запятыми; в настоящее время есть два диалекта, оба используются Microsoft Excel. Отдельный класс [`csv.writer`](https://python-all.ru/3.2/library/csv.html#csv.writer) будет генерировать файлы с разделителями-запятыми из последовательности кортежей или списков, заключая в кавычки строки, содержащие разделитель.536537> **См. также**538>539> **[**PEP 305**](https://python-all.ru/3.2/whatsnew/2.3.html) - API для CSV-файлов**540>541> Авторы и разработчики: Kevin Altis, Dave Cole, Andrew McNamara, Skip Montanaro, Cliff Wells.542543## PEP 307: Улучшения pickle544545Модули [`pickle`](https://python-all.ru/3.2/library/pickle.html#module-pickle) и `cPickle` привлекли некоторое внимание в ходе цикла разработки 2.3. В версии 2.2 классы нового стиля можно было без труда сериализовать с помощью pickle, но они сериализовались не очень компактно; [**PEP 307**](https://python-all.ru/3.2/whatsnew/2.3.html) приводит тривиальный пример, где класс нового стиля приводит к строке pickle в три раза длиннее, чем для классического класса.546547Решением стало изобретение нового протокола pickle. Функция [`pickle.dumps()`](https://python-all.ru/3.2/library/pickle.html#pickle.dumps) уже давно поддерживает флаг текст/бинар. В версии 2.3 этот флаг переопределен с логического на целочисленный: 0 – старый текстовый формат pickle, 1 – старый бинарный формат, а теперь 2 – новый формат, специфичный для 2.3. Новая константа, [`pickle.HIGHEST_PROTOCOL`](https://python-all.ru/3.2/library/pickle.html#pickle.HIGHEST_PROTOCOL), может использоваться для выбора самого навороченного доступного протокола.548549Десериализация pickle больше не считается безопасной операцией. В Python 2.2 модуль [`pickle`](https://python-all.ru/3.2/library/pickle.html#module-pickle) предоставлял хуки для попытки предотвратить десериализацию небезопасных классов (а именно атрибут `__safe_for_unpickling__`), но этот код никогда не был проверен аудитом, и поэтому в 2.3 он был целиком удален. Не следует десериализовать недоверенные данные в любой версии Python.550551Чтобы уменьшить накладные расходы при сериализации классов нового стиля, был добавлен новый интерфейс для настройки сериализации с помощью трёх специальных методов: `__getstate__()`, `__setstate__()` и `__getnewargs__()`. За полной семантикой этих методов обращайтесь к [**PEP 307**](https://python-all.ru/3.2/whatsnew/2.3.html).552553Для ещё большего сжатия pickle теперь можно использовать целочисленные коды вместо длинных строк для идентификации сериализованных классов. Python Software Foundation будет поддерживать список стандартизированных кодов; также существует диапазон кодов, зарезервированных для частного использования. В настоящее время коды не определены.554555> **См. также**556>557> **[**PEP 307**](https://python-all.ru/3.2/whatsnew/2.3.html) – расширения протокола pickle**558>559> Авторы и разработчики: Guido van Rossum и Tim Peters.560561## Расширенные срезы562563Ever since Python 1.4, the slicing syntax has supported an optional third “step” or “stride” argument. For example, these are all legal Python syntax: `L[1:10:2]`, `L[:-1:1]`, `L[::-1]`. This was added to Python at the request of the developers of Numerical Python, which uses the third argument extensively. However, Python’s built-in list, tuple, and string sequence types have never supported this feature, raising a [`TypeError`](https://python-all.ru/3.2/library/exceptions.html#TypeError) if you tried it. Michael Hudson contributed a patch to fix this shortcoming.564565Например, теперь можно легко извлечь элементы списка с чётными индексами:566567```python568>>> L = range(10)569>>> L[::2]570[0, 2, 4, 6, 8]571```572573Отрицательные значения также работают, чтобы создать копию того же списка в обратном порядке:574575```python576>>> L[::-1]577[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]578```579580Это также работает для кортежей, массивов и строк:581582```python583>>> s='abcd'584>>> s[::2]585'ac'586>>> s[::-1]587'dcba'588```589590Если у вас есть изменяемая последовательность, например список или массив, вы можете присваивать значение расширенному срезу или удалять его, но есть некоторые различия между присваиванием расширенным и обычным срезам. Присваивание обычному срезу может использоваться для изменения длины последовательности:591592```python593>>> a = range(3)594>>> a595[0, 1, 2]596>>> a[1:3] = [4, 5, 6]597>>> a598[0, 4, 5, 6]599```600601Расширенные срезы не настолько гибки. При присваивании расширенному срезу список в правой части оператора должен содержать то же количество элементов, что и заменяемый срез:602603```python604>>> a = range(4)605>>> a606[0, 1, 2, 3]607>>> a[::2]608[0, 2]609>>> a[::2] = [0, -1]610>>> a611[0, 1, -1, 3]612>>> a[::2] = [0,1,2]613Traceback (most recent call last):614  File "<stdin>", line 1, in ?615ValueError: attempt to assign sequence of size 3 to extended slice of size 2616```617618Удаление выполняется проще:619620```python621>>> a = range(4)622>>> a623[0, 1, 2, 3]624>>> a[::2]625[0, 2]626>>> del a[::2]627>>> a628[1, 3]629```630631One can also now pass slice objects to the [`__getitem__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__getitem__) methods of the built-in sequences:632633```python634>>> range(10).__getitem__(slice(0, 5, 2))635[0, 2, 4]636```637638Или использовать объекты срезов непосредственно в индексации:639640```python641>>> range(10)[slice(0, 5, 2)]642[0, 2, 4]643```644645Чтобы упростить реализацию последовательностей, поддерживающих расширенную нарезку, у объектов-срезов теперь есть метод `indices(length)()`, который по длине последовательности возвращает кортеж `(start, stop, step)`, который можно напрямую передать в [`range()`](https://python-all.ru/3.2/library/functions.html#range). `indices()` обрабатывает пропущенные и выходящие за границы индексы так же, как обычные срезы (и эта безобидная фраза скрывает множество запутанных деталей!). Метод предназначен для использования следующим образом:646647```python648class FakeSeq:649    ...650    def calc_item(self, i):651        ...652    def __getitem__(self, item):653        if isinstance(item, slice):654            indices = item.indices(len(self))655            return FakeSeq([self.calc_item(i) for i in range(*indices)])656        else:657            return self.calc_item(i)658```659660From this example you can also see that the built-in [`slice`](https://python-all.ru/3.2/library/functions.html#slice) object is now the type object for the slice type, and is no longer a function. This is consistent with Python 2.2, where [`int`](https://python-all.ru/3.2/library/functions.html#int), [`str`](https://python-all.ru/3.2/library/functions.html#str), etc., underwent the same change.661662## Прочие изменения языка663664Ниже перечислены все изменения, которые Python 2.3 вносит в ядро языка Python.665666- The [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield) statement is now always a keyword, as described in section [*PEP 255: Simple Generators*](https://python-all.ru/3.2/whatsnew/2.3.html#section-generators) of this document.667- A new built-in function [`enumerate()`](https://python-all.ru/3.2/library/functions.html#enumerate) was added, as described in section [*PEP 279: enumerate()*](https://python-all.ru/3.2/whatsnew/2.3.html#section-enumerate) of this document.668- Two new constants, [`True`](https://python-all.ru/3.2/library/constants.html#True) and [`False`](https://python-all.ru/3.2/library/constants.html#False) were added along with the built-in [`bool`](https://python-all.ru/3.2/library/functions.html#bool) type, as described in section [*PEP 285: A Boolean Type*](https://python-all.ru/3.2/whatsnew/2.3.html#section-bool) of this document.669- The [`int()`](https://python-all.ru/3.2/library/functions.html#int) type constructor will now return a long integer instead of raising an [`OverflowError`](https://python-all.ru/3.2/library/exceptions.html#OverflowError) when a string or floating-point number is too large to fit into an integer. This can lead to the paradoxical result that `isinstance(int(expression), int)` is false, but that seems unlikely to cause problems in practice.670- Встроенные типы теперь поддерживают расширенный синтаксис срезов, как описано в разделе [*Extended Slices*](https://python-all.ru/3.2/whatsnew/2.3.html#section-slices) этого документа.671- Новая встроенная функция `sum(iterable, start=0)()` суммирует числовые элементы в итерируемом объекте и возвращает их сумму. [`sum()`](https://python-all.ru/3.2/library/functions.html#sum) принимает только числа, то есть её нельзя использовать для конкатенации строк. (Предложено Алексом Мартелли.)672- `list.insert(pos, value)` used to insert *value* at the front of the list when *pos* was negative. The behaviour has now been changed to be consistent with slice indexing, so when *pos* is -1 the value will be inserted before the last element, and so forth.673- `list.index(value)`, which searches for *value* within the list and returns its index, now takes optional *start* and *stop* arguments to limit the search to only part of the list.674- У словарей появился новый метод `pop(key[, *default*])()`, который возвращает значение, соответствующее *key*, и удаляет эту пару ключ/значение из словаря. Если запрошенный ключ отсутствует в словаре, возвращается *default*, если он указан, и возбуждается [`KeyError`](https://python-all.ru/3.2/library/exceptions.html#KeyError), если нет.675676  ```python677  >>> d = {1:2}678  >>> d679  {1: 2}680  >>> d.pop(4)681  Traceback (most recent call last):682    File "stdin", line 1, in ?683  KeyError: 4684  >>> d.pop(1)685  2686  >>> d.pop(1)687  Traceback (most recent call last):688    File "stdin", line 1, in ?689  KeyError: 'pop(): dictionary is empty'690  >>> d691  {}692  >>>693  ```694695  Также появился новый метод класса `dict.fromkeys(iterable, value)()`, который создаёт словарь с ключами из переданного итератора *iterable* и всеми значениями, установленными в *value*, по умолчанию `None`.696697  (Патчи предоставлены Raymond Hettinger.)698699  Also, the [`dict()`](https://python-all.ru/3.2/library/stdtypes.html#dict) constructor now accepts keyword arguments to simplify creating small dictionaries:700701  ```python702  >>> dict(red=1, blue=2, green=3, black=4)703  {'blue': 2, 'black': 4, 'green': 3, 'red': 1}704  ```705706  (Автор: Just van Rossum.)707- The [`assert`](https://python-all.ru/3.2/reference/simple_stmts.html#assert) statement no longer checks the `__debug__` flag, so you can no longer disable assertions by assigning to `__debug__`. Running Python with the [*-O*](https://python-all.ru/3.2/using/cmdline.html#cmdoption-O) switch will still generate code that doesn’t execute any assertions.708- Most type objects are now callable, so you can use them to create new objects such as functions, classes, and modules. (This means that the `new` module can be deprecated in a future Python version, because you can now use the type objects available in the [`types`](https://python-all.ru/3.2/library/types.html#module-types) module.) For example, you can create a new module object with the following code:709710  ```python711  >>> import types712  >>> m = types.ModuleType('abc','docstring')713  >>> m714  <module 'abc' (built-in)>715  >>> m.__doc__716  'docstring'717  ```718- A new warning, [`PendingDeprecationWarning`](https://python-all.ru/3.2/library/exceptions.html#PendingDeprecationWarning) was added to indicate features which are in the process of being deprecated. The warning will *not* be printed by default. To check for use of features that will be deprecated in the future, supply *-Walways::PendingDeprecationWarning::* on the command line or use [`warnings.filterwarnings()`](https://python-all.ru/3.2/library/warnings.html#warnings.filterwarnings).719- The process of deprecating string-based exceptions, as in `raise "Error occurred"`, has begun. Raising a string will now trigger [`PendingDeprecationWarning`](https://python-all.ru/3.2/library/exceptions.html#PendingDeprecationWarning).720- Using `None` as a variable name will now result in a [`SyntaxWarning`](https://python-all.ru/3.2/library/exceptions.html#SyntaxWarning) warning. In a future version of Python, `None` may finally become a keyword.721- The `xreadlines()` method of file objects, introduced in Python 2.1, is no longer necessary because files now behave as their own iterator. `xreadlines()` was originally introduced as a faster way to loop over all the lines in a file, but now you can simply write `for line in file_obj`. File objects also have a new read-only `encoding` attribute that gives the encoding used by the file; Unicode strings written to the file will be automatically converted to bytes using the given encoding.722- Порядок разрешения методов, используемый классами нового стиля, изменился, хотя разницу вы заметите только при действительно сложной иерархии наследования. Классические классы это изменение не затрагивает. В Python 2.2 изначально использовалась топологическая сортировка предков класса, но в 2.3 теперь применяется алгоритм C3, описанный в статье [«A Monotonic Superclass Linearization for Dylan»](https://python-all.ru/3.2/whatsnew/2.3.html). Чтобы понять мотивацию этого изменения, прочтите статью Микеле Симониато [«Python 2.3 Method Resolution Order»](https://python-all.ru/3.2/whatsnew/2.3.html) или обсуждение в списке рассылки python-dev, начиная с сообщения по адресу [http://mail.python.org/pipermail/python-dev/2002-October/029035.html](https://python-all.ru/3.2/whatsnew/2.3.html). Самуэле Педрони первым указал на проблему и реализовал исправление, написав алгоритм C3.723- Python выполняет многопоточные программы, переключаясь между потоками после выполнения N байт-кодов. Значение N по умолчанию увеличено с 10 до 100 байт-кодов, что ускоряет однопоточные приложения за счёт уменьшения накладных расходов на переключение. Некоторые многопоточные приложения могут страдать от более медленного времени отклика, но это легко исправить, установив лимит обратно на более низкое значение с помощью `sys.setcheckinterval(N)()`. Предел можно получить с помощью новой функции [`sys.getcheckinterval()`](https://python-all.ru/3.2/library/sys.html#sys.getcheckinterval).724- One minor but far-reaching change is that the names of extension types defined by the modules included with Python now contain the module and a `'.'` in front of the type name. For example, in Python 2.2, if you created a socket and printed its `__class__`, you’d get this output:725726  ```python727  >>> s = socket.socket()728  >>> s.__class__729  <type 'socket'>730  ```731732  В 2.3 вы получите это:733734  ```python735  >>> s.__class__736  <type '_socket.socket'>737  ```738- Одна из известных несовместимостей между классами старого и нового стиля устранена: теперь можно присваивать значения атрибутам `__name__` и `__bases__` классов нового стиля. Существуют некоторые ограничения на то, что можно присваивать `__bases__`, аналогичные ограничениям на присваивание атрибуту `__class__` экземпляра.739740### Изменения строк741742- The [`in`](https://python-all.ru/3.2/reference/expressions.html#in) operator now works differently for strings. Previously, when evaluating `X in Y` where *X* and *Y* are strings, *X* could only be a single character. That’s now changed; *X* can be a string of any length, and `X in Y` will return [`True`](https://python-all.ru/3.2/library/constants.html#True) if *X* is a substring of *Y*. If *X* is the empty string, the result is always [`True`](https://python-all.ru/3.2/library/constants.html#True).743744  ```python745  >>> 'ab' in 'abcd'746  True747  >>> 'ad' in 'abcd'748  False749  >>> '' in 'abcd'750  True751  ```752753  Note that this doesn’t tell you where the substring starts; if you need that information, use the `find()` string method.754- The `strip()`, `lstrip()`, and `rstrip()` string methods now have an optional argument for specifying the characters to strip. The default is still to remove all whitespace characters:755756  ```python757  >>> '   abc '.strip()758  'abc'759  >>> '><><abc<><><>'.strip('<>')760  'abc'761  >>> '><><abc<><><>\n'.strip('<>')762  'abc<><><>\n'763  >>> u'\u4000\u4001abc\u4000'.strip(u'\u4000')764  u'\u4001abc'765  >>>766  ```767768  (Предложено Simon Brunning и реализовано Walter Dörwald.)769- The `startswith()` and `endswith()` string methods now accept negative numbers for the *start* and *end* parameters.770- Another new string method is `zfill()`, originally a function in the [`string`](https://python-all.ru/3.2/library/string.html#module-string) module. `zfill()` pads a numeric string with zeros on the left until it’s the specified width. Note that the `%` operator is still more flexible and powerful than `zfill()`.771772  ```python773  >>> '45'.zfill(4)774  '0045'775  >>> '12345'.zfill(4)776  '12345'777  >>> 'goofy'.zfill(6)778  '0goofy'779  ```780781  (Автор: Walter Dörwald.)782- A new type object, `basestring`, has been added. Both 8-bit strings and Unicode strings inherit from this type, so `isinstance(obj, basestring)` will return [`True`](https://python-all.ru/3.2/library/constants.html#True) for either kind of string. It’s a completely abstract type, so you can’t create `basestring` instances.783- Интернированные строки больше не бессмертны и теперь собираются сборщиком мусора обычным образом, когда единственная ссылка на них – из внутреннего словаря интернированных строк. (Реализовано Oren Tirosh.)784785### Оптимизации786787- Создание экземпляров классов нового стиля стало намного быстрее; теперь они быстрее, чем экземпляры классических классов!788- The `sort()` method of list objects has been extensively rewritten by Tim Peters, and the implementation is significantly faster.789- Умножение больших целых чисел теперь выполняется гораздо быстрее благодаря реализации умножения Карацубы – алгоритма, масштабируемость которого лучше, чем O(n\*n), необходимого для алгоритма умножения из начальной школы. (Оригинальный патч от Кристофера А. Крейга, значительно переработан Тимом Питерсом.)790- The `SET_LINENO` opcode is now gone. This may provide a small speed increase, depending on your compiler’s idiosyncrasies. See section [*Other Changes and Fixes*](https://python-all.ru/3.2/whatsnew/2.3.html#section-other) for a longer explanation. (Removed by Michael Hudson.)791- Объекты `xrange()` теперь имеют собственный итератор, что делает `for i in xrange(n)` немного быстрее, чем `for i in range(n)`. (Патч от Рэймонда Хеттингера.)792- Был выполнен ряд небольших перестановок в различных горячих точках для повышения производительности, например, встраивание функции или удаление некоторого кода. (В основном реализовано GvR, но многие люди внесли отдельные изменения.)793794Итоговый результат оптимизаций в версии 2.3: Python 2.3 выполняет тест pystone примерно на 25% быстрее, чем Python 2.2.795796## Новые, улучшенные и устаревшие модули797798Как обычно, стандартная библиотека Python получила ряд улучшений и исправлений ошибок. Вот частичный список наиболее заметных изменений, отсортированный по модулям в алфавитном порядке. За полным списком изменений обращайтесь к файлу `Misc/NEWS` в дереве исходных текстов, или просмотрите журналы CVS для получения всех подробностей.799800- Модуль [`array`](https://python-all.ru/3.2/library/array.html#module-array) теперь поддерживает массивы символов Unicode с использованием символа формата `'u'`. Массивы также теперь поддерживают оператор присваивания `+=` для добавления содержимого другого массива, и оператор присваивания `*=` для повторения массива. (Предложено Джейсоном Орендорффом.)801- Модуль `bsddb` заменен версией 4.1.6 пакета [PyBSDDB](https://python-all.ru/3.2/whatsnew/2.3.html), предоставляющего более полный интерфейс к транзакционным возможностям библиотеки BerkeleyDB.802803  Старая версия модуля переименована в `bsddb185` и больше не собирается автоматически; вам придется отредактировать `Modules/Setup`, чтобы включить её. Обратите внимание, что новый пакет `bsddb` предполагается совместимым со старым модулем, так что обязательно сообщайте об ошибках, если обнаружите несовместимости. При обновлении до Python 2.3, если новый интерпретатор скомпилирован с новой версией библиотеки BerkeleyDB, вам почти наверняка придется конвертировать файлы базы данных в новую версию. Это можно довольно легко сделать с помощью новых скриптов `db2pickle.py` и `pickle2db.py`, которые находятся в каталоге `Tools/scripts` дистрибутива. Если вы уже использовали пакет PyBSDDB и импортировали его как `bsddb3`, вам придется изменить операторы `import`, чтобы импортировать его как `bsddb`.804- Новый модуль [`bz2`](https://python-all.ru/3.2/library/bz2.html#module-bz2) – это интерфейс к библиотеке сжатия данных bz2. Данные, сжатые bz2, обычно меньше соответствующих данных, сжатых [`zlib`](https://python-all.ru/3.2/library/zlib.html#module-zlib). (Предложено Густаво Нимейером.)805- В новом модуле [`datetime`](https://python-all.ru/3.2/library/datetime.html#module-datetime) добавлен набор стандартных типов даты/времени. Подробнее см. следующий раздел.806- Класс `Extension` из Distutils теперь поддерживает дополнительный аргумент конструктора с именем *depends* для перечисления дополнительных исходных файлов, от которых зависит расширение. Это позволяет Distutils перекомпилировать модуль при изменении любого из файлов зависимостей. Например, если `sampmodule.c` включает заголовочный файл `sample.h`, вы создадите объект `Extension` так:807808  ```python809  ext = Extension("samp",810                  sources=["sampmodule.c"],811                  depends=["sample.h"])812  ```813814  Изменение `sample.h` приведет к перекомпиляции модуля. (Предложено Джереми Хилтоном.)815- Другие мелкие изменения в Distutils: теперь он проверяет переменные окружения `CC`, `CFLAGS`, `CPP`, `LDFLAGS` и `CPPFLAGS`, используя их для переопределения настроек конфигурации Python (предложено Робертом Вебером).816- Ранее модуль [`doctest`](https://python-all.ru/3.2/library/doctest.html#module-doctest) искал тестовые примеры только в docstrings публичных методов и функций, но теперь он также проверяет и приватные. Функция `DocTestSuite(()` создаёт объект [`unittest.TestSuite`](https://python-all.ru/3.2/library/unittest.html#unittest.TestSuite) из набора тестов [`doctest`](https://python-all.ru/3.2/library/doctest.html#module-doctest).817- Новая функция `gc.get_referents(object)()` возвращает список всех объектов, на которые ссылается *object*.818- Модуль [`getopt`](https://python-all.ru/3.2/library/getopt.html#module-getopt) получил новую функцию `gnu_getopt()`, которая поддерживает те же аргументы, что и существующая функция [`getopt()`](https://python-all.ru/3.2/library/getopt.html#module-getopt), но использует режим сканирования в стиле GNU. Существующая [`getopt()`](https://python-all.ru/3.2/library/getopt.html#module-getopt) прекращает обработку опций, как только встречает неопционный аргумент, но в режиме GNU обработка продолжается, то есть опции и аргументы могут смешиваться. Например:819820  ```python821  >>> getopt.getopt(['-f', 'filename', 'output', '-v'], 'f:v')822  ([('-f', 'filename')], ['output', '-v'])823  >>> getopt.gnu_getopt(['-f', 'filename', 'output', '-v'], 'f:v')824  ([('-f', 'filename'), ('-v', '')], ['output'])825  ```826827  (Автор: Peter Åstrand.)828- Модули [`grp`](https://python-all.ru/3.2/library/grp.html#module-grp), [`pwd`](https://python-all.ru/3.2/library/pwd.html#module-pwd) и [`resource`](https://python-all.ru/3.2/library/resource.html#module-resource) теперь возвращают расширенные кортежи:829830  ```python831  >>> import grp832  >>> g = grp.getgrnam('amk')833  >>> g.gr_name, g.gr_gid834  ('amk', 500)835  ```836- Модуль [`gzip`](https://python-all.ru/3.2/library/gzip.html#module-gzip) теперь может обрабатывать файлы размером более 2 ГБ.837- Новый модуль [`heapq`](https://python-all.ru/3.2/library/heapq.html#module-heapq) содержит реализацию алгоритма пирамидальной очереди (кучи). Куча – это структура данных, похожая на массив, которая хранит элементы в частично отсортированном порядке, так что для каждого индекса *k* выполняется `heap[k] <= heap[2*k+1]` и `heap[k] <= heap[2*k+2]`. Это позволяет быстро удалять наименьший элемент, а вставка нового элемента с сохранением свойства кучи выполняется за O(lg n). (Дополнительную информацию о структуре данных «очередь с приоритетом» см. на [http://www.nist.gov/dads/HTML/priorityque.html](https://python-all.ru/3.2/whatsnew/2.3.html).)838839  Модуль [`heapq`](https://python-all.ru/3.2/library/heapq.html#module-heapq) предоставляет функции `heappush()` и `heappop()` для добавления и удаления элементов с сохранением свойства кучи поверх некоторого другого изменяемого типа последовательности Python. Вот пример с использованием списка Python:840841  ```python842  >>> import heapq843  >>> heap = []844  >>> for item in [3, 7, 5, 11, 1]:845  ...    heapq.heappush(heap, item)846  ...847  >>> heap848  [1, 3, 5, 11, 7]849  >>> heapq.heappop(heap)850  1851  >>> heapq.heappop(heap)852  3853  >>> heap854  [5, 7, 11]855  ```856857  (Автор: Kevin O’Connor.)858- Интегрированная среда разработки IDLE обновлена с использованием кода из проекта IDLEfork ([http://idlefork.sf.net](https://python-all.ru/3.2/whatsnew/2.3.html)). Наиболее примечательная особенность: разрабатываемый код теперь выполняется в подпроцессе, что устраняет необходимость в ручных вызовах `reload()`. Основной код IDLE включён в стандартную библиотеку в виде пакета `idlelib`.859- Модуль [`imaplib`](https://python-all.ru/3.2/library/imaplib.html#module-imaplib) теперь поддерживает IMAP через SSL. (Предложено Пирсом Лаудером и Тино Ланге.)860- Модуль [`itertools`](https://python-all.ru/3.2/library/itertools.html#module-itertools) содержит ряд полезных функций для работы с итераторами, вдохновленных различными функциями из языков ML и Haskell. Например, `itertools.ifilter(predicate, iterator)` возвращает все элементы итератора, для которых функция `predicate()` возвращает [`True`](https://python-all.ru/3.2/library/constants.html#True), а `itertools.repeat(obj, N)` возвращает `obj` *N* раз. В модуле есть и другие функции; подробности см. в справочной документации пакета. (Предложено Рэймондом Хеттингером.)861- Две новые функции в модуле [`math`](https://python-all.ru/3.2/library/math.html#module-math), `degrees(rads)()` и `radians(degs)()`, преобразуют радианы в градусы и наоборот. Другие функции модуля [`math`](https://python-all.ru/3.2/library/math.html#module-math), такие как [`math.sin()`](https://python-all.ru/3.2/library/math.html#math.sin) и [`math.cos()`](https://python-all.ru/3.2/library/math.html#math.cos), всегда требовали входные значения в радианах. Кроме того, в [`math.log()`](https://python-all.ru/3.2/library/math.html#math.log) добавлен необязательный аргумент *base*, чтобы упростить вычисление логарифмов по основаниям, отличным от `e` и `10`. (Предложено Раймондом Хеттингером.)862- В модуль [`posix`](https://python-all.ru/3.2/library/posix.html#module-posix), лежащий в основе модуля [`os`](https://python-all.ru/3.2/library/os.html#module-os), добавлено несколько новых функций POSIX: `getpgid()`, `killpg()`, `lchown()`, `loadavg()`, `major()`, `makedev()`, `minor()` и `mknod()`. (Предложено Густаво Нимейером, Гертом Янсеном и Денисом С. Откидачем.)863- В модуле [`os`](https://python-all.ru/3.2/library/os.html#module-os) семейство функций `*stat()` теперь может сообщать доли секунды во временной метке. Такие временные метки представляются числами с плавающей запятой, аналогично значению, возвращаемому [`time.time()`](https://python-all.ru/3.2/library/time.html#time.time).864865  В ходе тестирования было обнаружено, что некоторые приложения сломаются, если временные метки будут числами с плавающей запятой. Для совместимости при использовании кортежного интерфейса `stat_result` временные метки будут представляться целыми числами. При использовании именованных полей (функция, впервые появившаяся в Python 2.2) временные метки по-прежнему представляются целыми числами, если только не вызвать [`os.stat_float_times()`](https://python-all.ru/3.2/library/os.html#os.stat_float_times) для включения возврата чисел с плавающей запятой:866867  ```python868  >>> os.stat("/tmp").st_mtime869  1034791200870  >>> os.stat_float_times(True)871  >>> os.stat("/tmp").st_mtime872  1034791200.6335014873  ```874875  В Python 2.4 значение по умолчанию изменится – всегда будут возвращаться числа с плавающей точкой.876877  Разработчикам приложений следует включать эту возможность только в том случае, если все их библиотеки корректно работают с метками времени с плавающей точкой, или если они используют API кортежей. При использовании эту возможность следует активировать на уровне приложения, а не пытаться включать её для каждого отдельного вызова.878- Модуль [`optparse`](https://python-all.ru/3.2/library/optparse.html#module-optparse) содержит новый анализатор аргументов командной строки, который может преобразовывать значения опций в определенный тип Python и автоматически генерировать сообщение об использовании. Подробнее см. следующий раздел.879- Старый и никогда не документированный модуль `linuxaudiodev` объявлен устаревшим, и добавлена новая версия [`ossaudiodev`](https://python-all.ru/3.2/library/ossaudiodev.html#module-ossaudiodev). Модуль переименован, поскольку звуковые драйверы OSS могут использоваться на платформах, отличных от Linux, а интерфейс также был приведен в порядок и обновлен различными способами. (Предложено Грегом Уордом и Николасом ФитцРой-Дейлом.)880- Новый модуль [`platform`](https://python-all.ru/3.2/library/platform.html#module-platform) содержит ряд функций, которые пытаются определить различные свойства платформы, на которой вы работаете. Есть функции для получения архитектуры, типа процессора, версии ОС Windows и даже версии дистрибутива Linux. (Предложено Марком-Андре Лембургом.)881- Объекты синтаксического анализатора, предоставляемые модулем `pyexpat`, теперь могут опционально буферизировать символьные данные, что приводит к меньшему количеству вызовов обработчика символьных данных и, следовательно, к более высокой производительности. Установка атрибута `buffer_text` объекта анализатора в [`True`](https://python-all.ru/3.2/library/constants.html#True) включит буферизацию.882- Функция `sample(population, k)()` была добавлена в модуль [`random`](https://python-all.ru/3.2/library/random.html#module-random). *population* – это последовательность или объект `xrange`, содержащий элементы генеральной совокупности, а `sample()` выбирает *k* элементов из совокупности без замены выбранных элементов. *k* может быть любым значением до `len(population)`. Например:883884  ```python885  >>> days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'St', 'Sn']886  >>> random.sample(days, 3)      # Выбрать 3 элемента887  ['St', 'Sn', 'Th']888  >>> random.sample(days, 7)      # Выбрать 7 элементов889  ['Tu', 'Th', 'Mo', 'We', 'St', 'Fr', 'Sn']890  >>> random.sample(days, 7)      # Выбрать 7 снова891  ['We', 'Mo', 'Sn', 'Fr', 'Tu', 'St', 'Th']892  >>> random.sample(days, 8)      # Нельзя выбрать восемь893  Traceback (most recent call last):894    File "<stdin>", line 1, in ?895    File "random.py", line 414, in sample896        raise ValueError, "sample larger than population"897  ValueError: sample larger than population898  >>> random.sample(xrange(1,10000,2), 10)   # Выбрать десять нечётных чисел меньше 10000899  [3407, 3805, 1505, 7023, 2401, 2267, 9733, 3151, 8083, 9195]900  ```901902  Модуль [`random`](https://python-all.ru/3.2/library/random.html#module-random) теперь использует новый алгоритм – вихрь Мерсенна, реализованный на C. Он быстрее и более изучен, чем предыдущий алгоритм.903904  (Все изменения выполнены Raymond Hettinger.)905- Модуль [`readline`](https://python-all.ru/3.2/library/readline.html#module-readline) также получил ряд новых функций: `get_history_item()`, `get_current_history_length()` и `redisplay()`.906- Модули `rexec` и `Bastion` объявлены мёртвыми, и попытки их импорта завершатся ошибкой [`RuntimeError`](https://python-all.ru/3.2/library/exceptions.html#RuntimeError). Классы нового стиля предоставляют новые способы выхода из ограниченной среды выполнения, предоставляемой `rexec`, и никто не заинтересован в их исправлении или не имеет времени на это. Если у вас есть приложения, использующие `rexec`, перепишите их для использования чего-то другого.907908  (Использование Python 2.2 или 2.1 не сделает приложения безопаснее, поскольку в этих версиях есть известные ошибки в модуле `rexec`. Повторюсь: если используется `rexec`, следует немедленно прекратить его использование.)909- Модуль `rotor` устарел, поскольку используемый в нём алгоритм шифрования не считается безопасным. Если требуется шифрование, воспользуйтесь одним из нескольких модулей AES для Python, доступных отдельно.910- Модуль [`shutil`](https://python-all.ru/3.2/library/shutil.html#module-shutil) получил функцию `move(src, dest)()`, которая рекурсивно перемещает файл или каталог в новое место.911- В модуль [`signal`](https://python-all.ru/3.2/library/signal.html#module-signal) была добавлена поддержка более продвинутой обработки сигналов POSIX, однако позже она была удалена, поскольку обеспечить её надёжную работу на разных платформах не удалось.912- Модуль [`socket`](https://python-all.ru/3.2/library/socket.html#module-socket) теперь поддерживает тайм-ауты. Можно вызвать метод `settimeout(t)()` на объекте сокета, чтобы установить тайм-аут в *t* секунд. Последующие операции с сокетом, которые выполняются дольше *t* секунд, будут прерваны и возбудят исключение [`socket.timeout`](https://python-all.ru/3.2/library/socket.html#socket.timeout).913914  Исходная реализация тайм-аута была создана Тимом О'Мэлли. Майкл Гилфикс интегрировал её в модуль [`socket`](https://python-all.ru/3.2/library/socket.html#module-socket) Python и провёл её через длительное рецензирование. После того как код был принят, Гвидо ван Россум переписал его части. (Это хороший пример совместного процесса разработки в действии.)915- В Windows модуль [`socket`](https://python-all.ru/3.2/library/socket.html#module-socket) теперь поставляется с поддержкой Secure Sockets Layer (SSL).916- Значение макроса C `PYTHON_API_VERSION` теперь доступно на уровне Python как `sys.api_version`. Текущее исключение можно очистить, вызвав новую функцию `sys.exc_clear()`.917- Новый модуль [`tarfile`](https://python-all.ru/3.2/library/tarfile.html#module-tarfile) позволяет читать и записывать архивные файлы в формате **tar**. (Автор: Lars Gustäbel.)918- Новый модуль [`textwrap`](https://python-all.ru/3.2/library/textwrap.html#module-textwrap) содержит функции для обёртывания строк, содержащих абзацы текста. Функция `wrap(text, width)()` принимает строку и возвращает список, содержащий текст, разбитый на строки длиной не более заданной ширины. Функция `fill(text, width)()` возвращает одну строку, переформатированную так, чтобы умещаться в строки длиной не более заданной ширины. (Как вы можете догадаться, `fill()` построена на основе `wrap()`. Например:919920  ```python921  >>> import textwrap922  >>> paragraph = "Not a whit, we defy augury: ... more text ..."923  >>> textwrap.wrap(paragraph, 60)924  ["Not a whit, we defy augury: there's a special providence in",925   "the fall of a sparrow. If it be now, 'tis not to come; if it",926   ...]927  >>> print textwrap.fill(paragraph, 35)928  Not a whit, we defy augury: there's929  a special providence in the fall of930  a sparrow. If it be now, 'tis not931  to come; if it be not to come, it932  will be now; if it be not now, yet933  it will come: the readiness is all.934  >>>935  ```936937  Модуль также содержит класс `TextWrapper`, который фактически реализует стратегию переноса текста. Как класс `TextWrapper`, так и функции `wrap()` и `fill()` поддерживают ряд дополнительных именованных аргументов для точной настройки форматирования; подробности см. в документации модуля. (Автор: Greg Ward.)938- Модули `thread` и [`threading`](https://python-all.ru/3.2/library/threading.html#module-threading) теперь имеют вспомогательные модули `dummy_thread` и [`dummy_threading`](https://python-all.ru/3.2/library/dummy_threading.html#module-dummy_threading), которые предоставляют фиктивную реализацию интерфейса модуля `thread` для платформ, не поддерживающих потоки. Цель – упростить модули, учитывающие наличие потоков (те, которые *не* полагаются на потоки для своей работы), разместив в начале следующий код:939940  ```python941  try:942      import threading as _threading943  except ImportError:944      import dummy_threading as _threading945  ```946947  В этом примере `_threading` используется в качестве имени модуля, чтобы подчеркнуть, что используемый модуль не обязательно является настоящим модулем [`threading`](https://python-all.ru/3.2/library/threading.html#module-threading). Код может вызывать функции и использовать классы из `_threading` независимо от того, поддерживаются ли потоки, что позволяет избежать инструкции [`if`](https://python-all.ru/3.2/reference/compound_stmts.html#if) и делает код немного понятнее. Этот модуль не заставит магическим образом многопоточный код работать без потоков; код, ожидающий возврата или выполнения другого потока, просто зависнет навсегда.948- Функция `strptime()` модуля [`time`](https://python-all.ru/3.2/library/time.html#module-time) долгое время вызывала неудобства, поскольку использовала реализацию `strptime()` из библиотеки C платформы, а на разных платформах иногда встречались странные ошибки. Бретт Кэннон предоставил переносимую реализацию, написанную на чистом Python, которая должна вести себя одинаково на всех платформах.949- Новый модуль [`timeit`](https://python-all.ru/3.2/library/timeit.html#module-timeit) помогает измерять время выполнения фрагментов кода Python. Файл `timeit.py` можно запускать непосредственно из командной строки, или же можно импортировать и использовать класс `Timer` модуля. Вот короткий пример, определяющий, что быстрее: преобразовать 8-битную строку в Unicode путём добавления пустой строки Unicode или с помощью функции `unicode()`:950951  ```python952  import timeit953954  timer1 = timeit.Timer('unicode("abc")')955  timer2 = timeit.Timer('"abc" + u""')956957  # Провести три испытания958  print timer1.repeat(repeat=3, number=100000)959  print timer2.repeat(repeat=3, number=100000)960961  # На моём ноутбуке это выводит:962  # [0.36831796169281006, 0.37441694736480713, 0.35304892063140869]963  # [0.17574405670166016, 0.18193507194519043, 0.17565798759460449]964  ```965- Модуль `Tix` получил различные исправления ошибок и обновления для текущей версии пакета Tix.966- Модуль `Tkinter` теперь работает с версией Tcl, поддерживающей потоки. Модель потоков Tcl требует, чтобы виджеты были доступны только из того потока, в котором они созданы; доступ из другого потока может привести к панике Tcl. Для определённых интерфейсов Tcl `Tkinter` теперь автоматически избегает этого при доступе к виджету из другого потока, упаковывая команду, передавая её в правильный поток и ожидая результатов. Другие интерфейсы не могут обрабатываться автоматически, но `Tkinter` теперь будет вызывать исключение при таком доступе, чтобы вы хотя бы могли узнать о проблеме. См. [http://mail.python.org/pipermail/python-dev/2002-December/031107.html](https://python-all.ru/3.2/whatsnew/2.3.html) для более подробного объяснения этого изменения. (Реализовано Мартином фон Лёвисом.)967- Вызов методов Tcl через `_tkinter` теперь возвращает не только строки. Если Tcl возвращает другие объекты, они преобразуются в эквивалент Python, если таковой существует, или оборачиваются в объект `_tkinter.Tcl_Obj`, если эквивалента нет. Этим поведением можно управлять через метод `wantobjects()` объектов `tkapp`.968969  При использовании `_tkinter` через модуль `Tkinter` (как и делают большинство приложений Tkinter) эта возможность всегда включена. Это не должно вызывать проблем совместимости, поскольку Tkinter всегда по возможности преобразует строковые результаты в типы Python.970971  Если будут обнаружены несовместимости, можно восстановить старое поведение, установив переменную `wantobjects` в модуле `Tkinter` в значение false перед созданием первого объекта `tkapp`.972973  ```python974  import Tkinter975  Tkinter.wantobjects = 0976  ```977978  Любые проблемы, вызванные этим изменением, следует сообщать как об ошибке.979- В модуле `UserDict` появился новый класс `DictMixin`, который определяет все методы словаря для классов, уже имеющих минимальный интерфейс отображения. Это значительно упрощает написание классов, которые должны быть взаимозаменяемы со словарями, например классов в модуле [`shelve`](https://python-all.ru/3.2/library/shelve.html#module-shelve).980981  Добавление примеси в качестве суперкласса предоставляет полный интерфейс словаря, если класс определяет [`__getitem__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__getitem__), [`__setitem__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__setitem__), [`__delitem__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__delitem__) и `keys()`. Например:982983  ```python984  >>> import UserDict985  >>> class SeqDict(UserDict.DictMixin):986  ...     """Подобие словаря, реализованное с помощью списков."""987  ...     def __init__(self):988  ...         self.keylist = []989  ...         self.valuelist = []990  ...     def __getitem__(self, key):991  ...         try:992  ...             i = self.keylist.index(key)993  ...         except ValueError:994  ...             raise KeyError995  ...         return self.valuelist[i]996  ...     def __setitem__(self, key, value):997  ...         try:998  ...             i = self.keylist.index(key)999  ...             self.valuelist[i] = value1000  ...         except ValueError:1001  ...             self.keylist.append(key)1002  ...             self.valuelist.append(value)1003  ...     def __delitem__(self, key):1004  ...         try:1005  ...             i = self.keylist.index(key)1006  ...         except ValueError:1007  ...             raise KeyError1008  ...         self.keylist.pop(i)1009  ...         self.valuelist.pop(i)1010  ...     def keys(self):1011  ...         return list(self.keylist)1012  ...1013  >>> s = SeqDict()1014  >>> dir(s)      # Посмотреть, что другие методы словаря реализованы1015  ['__cmp__', '__contains__', '__delitem__', '__doc__', '__getitem__',1016   '__init__', '__iter__', '__len__', '__module__', '__repr__',1017   '__setitem__', 'clear', 'get', 'has_key', 'items', 'iteritems',1018   'iterkeys', 'itervalues', 'keylist', 'keys', 'pop', 'popitem',1019   'setdefault', 'update', 'valuelist', 'values']1020  ```10211022  (Автор: Raymond Hettinger.)1023- Реализация DOM в модуле [`xml.dom.minidom`](https://python-all.ru/3.2/library/xml.dom.minidom.html#module-xml.dom.minidom) теперь может генерировать вывод XML в определённой кодировке, если передать необязательный аргумент encoding методам `toxml()` и `toprettyxml()` узлов DOM.1024- Модуль `xmlrpclib` теперь поддерживает расширение XML-RPC для обработки нулевых значений данных, таких как `None` в Python. Нулевые значения всегда поддерживаются при демаршалинге ответа XML-RPC. Чтобы сгенерировать запросы, содержащие `None`, необходимо передать истинное значение для параметра *allow\_none* при создании экземпляра `Marshaller`.1025- Новый модуль `DocXMLRPCServer` позволяет писать самодокументируемые XML-RPC серверы. Запустите его в демонстрационном режиме (как программу), чтобы увидеть его в действии. Если направить веб-браузер на RPC-сервер, будет показана документация в стиле pydoc; если направить xmlrpclib на сервер, можно вызывать реальные методы. (Автор: Brian Quinlan.)1026- Добавлена поддержка интернационализированных доменных имен (RFC 3454, 3490, 3491, 3492). Кодировка "idna" может использоваться для преобразования между доменным именем в Unicode и его ASCII-совместимой кодировкой (ACE).10271028  ```python1029  >{}>{}> u"www.Alliancefrançaise.nu".encode("idna")1030  'www.xn--alliancefranaise-npb.nu'1031  ```10321033  Модуль [`socket`](https://python-all.ru/3.2/library/socket.html#module-socket) также был расширен для прозрачного преобразования Unicode-имён хостов в версию ACE перед передачей их в библиотеку C. Модули, работающие с именами хостов, такие как `httplib` и [`ftplib`](https://python-all.ru/3.2/library/ftplib.html#module-ftplib)), также поддерживают Unicode-имена хостов; `httplib` также отправляет HTTP-заголовки `Host`, используя ACE-версию доменного имени. `urllib` поддерживает Unicode-URL с не-ASCII именами хостов, если часть `path` URL содержит только ASCII.10341035  Для реализации этого изменения были добавлены модуль [`stringprep`](https://python-all.ru/3.2/library/stringprep.html#module-stringprep), инструмент `mkstringprep` и кодировка `punycode`.10361037### Типы даты/времени10381039Типы даты и времени, подходящие для представления меток времени, были добавлены в виде модуля [`datetime`](https://python-all.ru/3.2/library/datetime.html#module-datetime). Типы не поддерживают разные календари или множество навороченных функций и придерживаются основ представления времени.10401041Три основных типа: `date` (день, месяц и год), [`time`](https://python-all.ru/3.2/library/time.html#module-time) (час, минута и секунда) и [`datetime`](https://python-all.ru/3.2/library/datetime.html#module-datetime), который содержит все атрибуты как `date`, так и [`time`](https://python-all.ru/3.2/library/time.html#module-time). Также есть класс `timedelta`, представляющий разницу между двумя моментами времени, а логика часовых поясов реализована классами, наследующими от абстрактного класса `tzinfo`.10421043Экземпляры `date` и [`time`](https://python-all.ru/3.2/library/time.html#module-time) можно создать, передав именованные аргументы соответствующему конструктору, например `datetime.date(year=1972, month=10, day=15)`, или используя один из нескольких методов класса. Например, метод класса `date.today()` возвращает текущую локальную дату.10441045После создания экземпляры классов даты/времени являются неизменяемыми. Существует ряд методов для создания форматированных строк из объектов:10461047```python1048>>> import datetime1049>>> now = datetime.datetime.now()1050>>> now.isoformat()1051'2002-12-30T21:27:03.994956'1052>>> now.ctime()  # Доступно только для date, datetime1053'Mon Dec 30 21:27:03 2002'1054>>> now.strftime('%Y %d %b')1055'2002 30 Dec'1056```10571058Метод `replace()` позволяет изменить одно или несколько полей экземпляра `date` или [`datetime`](https://python-all.ru/3.2/library/datetime.html#module-datetime), возвращая новый экземпляр:10591060```python1061>>> d = datetime.datetime.now()1062>>> d1063datetime.datetime(2002, 12, 30, 22, 15, 38, 827738)1064>>> d.replace(year=2001, hour = 12)1065datetime.datetime(2001, 12, 30, 12, 15, 38, 827738)1066>>>1067```10681069Экземпляры можно сравнивать, хешировать и преобразовывать в строки (результат совпадает с результатом `isoformat()`). Экземпляры `date` и [`datetime`](https://python-all.ru/3.2/library/datetime.html#module-datetime) можно вычитать друг из друга и складывать с экземплярами `timedelta`. Самый большой недостающий элемент – отсутствие поддержки в стандартной библиотеке разбора строк для получения экземпляра `date` или [`datetime`](https://python-all.ru/3.2/library/datetime.html#module-datetime).10701071За дополнительной информацией обращайтесь к справочной документации модуля. (Предоставлено Тимом Питерсом.)10721073### Модуль optparse10741075Модуль [`getopt`](https://python-all.ru/3.2/library/getopt.html#module-getopt) предоставляет простой разбор аргументов командной строки. Новый модуль [`optparse`](https://python-all.ru/3.2/library/optparse.html#module-optparse) (первоначально назывался Optik) обеспечивает более сложный разбор командной строки, который следует соглашениям Unix, автоматически создает вывод для [*--help*](https://python-all.ru/3.2/using/cmdline.html#cmdoption--help) и может выполнять разные действия для разных опций.10761077Сначала создается экземпляр `OptionParser`, которому сообщается, какие опции есть у программы.10781079```python1080import sys1081from optparse import OptionParser10821083op = OptionParser()1084op.add_option('-i', '--input',1085              action='store', type='string', dest='input',1086              help='set input filename')1087op.add_option('-l', '--length',1088              action='store', type='int', dest='length',1089              help='set maximum length of output')1090```10911092Разбор командной строки выполняется вызовом метода `parse_args()`.10931094```python1095options, args = op.parse_args(sys.argv[1:])1096print options1097print args1098```10991100Метод возвращает объект, содержащий все значения параметров и список строк с остальными аргументами.11011102Теперь запуск скрипта с различными аргументами работает так, как и ожидается. Обратите внимание, что аргумент length автоматически преобразуется в целое число.11031104```python1105$ ./python opt.py -i data arg11106<Values at 0x400cad4c: {'input': 'data', 'length': None}>1107['arg1']1108$ ./python opt.py --input=data --length=41109<Values at 0x400cad2c: {'input': 'data', 'length': 4}>1110[]1111$1112```11131114Справочное сообщение создаётся автоматически:11151116```python1117$ ./python opt.py --help1118usage: opt.py [options]11191120options:1121  -h, --help            show this help message and exit1122  -iINPUT, --input=INPUT1123                        set input filename1124  -lLENGTH, --length=LENGTH1125                        set maximum length of output1126$1127```11281129Подробнее см. документацию модуля.11301131Optik был написан Грегом Уордом (Greg Ward) с учётом предложений участников Getopt SIG.11321133## Pymalloc: специализированный распределитель объектов11341135Pymalloc – специализированный распределитель объектов, написанный Владимиром Марангозовым, был добавлен в Python 2.1. Pymalloc предназначен для более быстрой работы, чем системный `malloc()`, и для меньших накладных расходов памяти при типичных для программ Python шаблонах выделения. Распределитель использует функцию `malloc()` из C для получения больших пулов памяти, а затем удовлетворяет мелкие запросы на выделение из этих пулов.11361137В версиях 2.1 и 2.2 pymalloc был экспериментальной функцией и не включался по умолчанию; его нужно было явно включить при компиляции Python, передав опцию *--with-pymalloc* скрипту **configure**. В версии 2.3 pymalloc получил дальнейшие улучшения и теперь включен по умолчанию; для его отключения нужно указать *--without-pymalloc*.11381139Для кода на Python это изменение незаметно, однако pymalloc может выявить ошибки в C-расширениях. Авторам модулей-расширений на C следует тестировать свой код с включённым pymalloc, поскольку некорректный код может приводить к аварийному завершению программы.11401141Существует одна особенно распространенная ошибка, вызывающая проблемы. В C API Python есть ряд функций выделения памяти, которые ранее были просто псевдонимами для `malloc()` и `free()` из библиотеки C; это означало, что если случайно вызвать несоответствующие функции, ошибка не будет заметна. Когда распределитель объектов включен, эти функции больше не являются псевдонимами `malloc()` и `free()`, и вызов неправильной функции для освобождения памяти может привести к аварийному дампу. Например, если память была выделена с помощью `PyObject_Malloc()`, ее нужно освобождать с помощью `PyObject_Free()`, а не `free()`. Некоторые модули, входящие в состав Python, столкнулись с этой проблемой и были исправлены; несомненно, есть и другие сторонние модули, имеющие ту же проблему.11421143В рамках этого изменения запутанные множественные интерфейсы для выделения памяти были объединены в два семейства API. Память, выделенная функциями одного семейства, не должна обрабатываться функциями другого. Одно семейство предназначено для выделения блоков памяти, другое – специально для выделения объектов Python.11441145- Для выделения и освобождения неспециализированного блока памяти используйте семейство «сырой памяти»: [`PyMem_Malloc()`](https://python-all.ru/3.2/c-api/memory.html#PyMem_Malloc), [`PyMem_Realloc()`](https://python-all.ru/3.2/c-api/memory.html#PyMem_Realloc) и [`PyMem_Free()`](https://python-all.ru/3.2/c-api/memory.html#PyMem_Free).1146- Семейство «объектной памяти» – это интерфейс к механизму pymalloc, описанному выше, и ориентировано на большое количество «мелких» выделений: `PyObject_Malloc()`, `PyObject_Realloc()` и `PyObject_Free()`.1147- Для выделения и освобождения объектов Python используйте семейство «объектных» функций: [`PyObject_New()`](https://python-all.ru/3.2/c-api/allocation.html#PyObject_New), [`PyObject_NewVar()`](https://python-all.ru/3.2/c-api/allocation.html#PyObject_NewVar) и [`PyObject_Del()`](https://python-all.ru/3.2/c-api/allocation.html#PyObject_Del).11481149Благодаря большой работе Тима Питерса, pymalloc в версии 2.3 также предоставляет средства отладки для обнаружения перезаписи памяти и двойного освобождения как в модулях расширения, так и в самом интерпретаторе. Чтобы включить эту поддержку, скомпилируйте отладочную версию интерпретатора Python, запустив **configure** с опцией *--with-pydebug*.11501151В помощь разработчикам расширений в исходных кодах Python 2.3 распространяется заголовочный файл `Misc/pymemcompat.h`, который позволяет расширениям Python использовать интерфейсы выделения памяти версии 2.3 при компиляции с любой версией Python начиная с 1.5.2. Этот файл можно скопировать из дистрибутива исходных кодов Python и включить в исходный код своего расширения.11521153> **См. также**1154>1155> **[http://svn.python.org/view/python/trunk/Objects/obmalloc.c](https://python-all.ru/3.2/whatsnew/2.3.html)**1156>1157> Полные сведения о реализации pymalloc см. в комментариях в начале файла1158>1159> `Objects/obmalloc.c`1160>1161> в исходных кодах Python. Приведенная выше ссылка указывает на этот файл в SVN-обозревателе python.org.11621163## Изменения в сборке и C API11641165Изменения процесса сборки Python и C API включают:11661167- Реализация обнаружения циклов, используемая сборщиком мусора, доказала свою стабильность, и теперь она обязательна. Невозможно скомпилировать Python без нее, а флаг *--with-cycle-gc* для **configure** был удален.1168- Python теперь может быть опционально собран как разделяемая библиотека (`libpython2.3.so`) с помощью указания *--enable-shared* при запуске скрипта **configure**. (Автор: Ондрей Палковски.)1169- Макросы `DL_EXPORT` и `DL_IMPORT` теперь устарели. Функции инициализации модулей расширения Python теперь должны объявляться с использованием нового макроса `PyMODINIT_FUNC`, в то время как ядро Python обычно использует макросы `PyAPI_FUNC` и `PyAPI_DATA`.1170- Интерпретатор можно скомпилировать без строк документации для встроенных функций и модулей, передав *--without-doc-strings* скрипту **configure**. Это делает исполняемый файл Python примерно на 10% меньше, но также означает, что нельзя получить справку по встроенным модулям Python. (Автор: Густаво Нимейер.)1171- Макрос `PyArg_NoArgs()` теперь устарел, и код, использующий его, следует изменить. Для Python 2.2 и новее таблица определений методов может указывать флаг [`METH_NOARGS`](https://python-all.ru/3.2/c-api/structures.html#METH_NOARGS), сигнализирующий об отсутствии аргументов; проверку аргументов можно удалить. Если важна совместимость с версиями Python до 2.2, код может использовать `PyArg_ParseTuple(args, "")`, но это будет медленнее, чем использование [`METH_NOARGS`](https://python-all.ru/3.2/c-api/structures.html#METH_NOARGS).1172- [`PyArg_ParseTuple()`](https://python-all.ru/3.2/c-api/arg.html#PyArg_ParseTuple) принимает новые символы формата для различных размеров беззнаковых целых: `B` для `unsigned char`, `H` для `unsigned short int`, `I` для `unsigned int` и `K` для `unsigned long long`.1173- Была добавлена новая функция `PyObject_DelItemString(mapping, char *key)()` как сокращение для `PyObject_DelItem(mapping, PyString_New(key))`.1174- Файловые объекты теперь по-другому управляют своим внутренним строковым буфером, увеличивая его экспоненциально при необходимости. В результате тесты производительности в `Lib/test/test_bufio.py` существенно ускорились (с 57 секунд до 1,7 секунды по одному из измерений).1175- Теперь можно определять методы класса и статические методы для типа расширения C, устанавливая флаги [`METH_CLASS`](https://python-all.ru/3.2/c-api/structures.html#METH_CLASS) или [`METH_STATIC`](https://python-all.ru/3.2/c-api/structures.html#METH_STATIC) в структуре [`PyMethodDef`](https://python-all.ru/3.2/c-api/structures.html#PyMethodDef) метода.1176- Python теперь включает копию исходного кода Expat XML-парсера, устраняя зависимость от системной версии или локальной установки Expat.1177- Если вы динамически выделяете объекты типов в своём расширении, следует учитывать изменение правил, касающихся атрибутов `__module__` и `__name__`. Вкратце: необходимо убедиться, что словарь типа содержит ключ `'__module__'`; делать имя модуля частью имени типа до последней точки больше не будет желаемого эффекта. Подробнее см. в справочной документации по API или в исходном коде.11781179### Изменения, специфичные для платформ11801181Поддержка порта для IBM OS/2 с использованием среды выполнения EMX была объединена в основное дерево исходных кодов Python. EMX – это уровень эмуляции POSIX поверх системных API OS/2. Порт Python для EMX пытается поддерживать все возможности, подобные POSIX, предоставляемые средой EMX, и в основном это удается; `fork()` и [`fcntl()`](https://python-all.ru/3.2/library/fcntl.html#module-fcntl) ограничены ограничениями нижележащего уровня эмуляции. Стандартный порт OS/2, использующий компилятор IBM Visual Age, также получил поддержку чувствительной к регистру семантики импорта в рамках интеграции порта EMX в CVS. (Автор: Эндрю Макинтайр.)11821183В MacOS большинство модулей toolbox были слабо связаны для улучшения обратной совместимости. Это означает, что модули больше не будут загружаться с ошибкой, если в текущей версии ОС отсутствует отдельная процедура. Вместо этого вызов отсутствующей процедуры вызовет исключение. (Автор: Jack Jansen.)11841185RPM spec-файлы, находящиеся в каталоге `Misc/RPM/` в дистрибутиве исходных кодов Python, были обновлены для версии 2.3. (Автор: Шон Райфшнайдер.)11861187Другие новые платформы, теперь поддерживаемые Python, включают AtheOS ([http://www.atheos.cx/](https://python-all.ru/3.2/whatsnew/2.3.html)), GNU/Hurd и OpenVMS.11881189## Другие изменения и исправления11901191Как обычно, по всему дереву исходных кодов было разбросано множество других улучшений и исправлений ошибок. Поиск по журналам изменений CVS показывает, что между Python 2.2 и 2.3 было применено 523 патча и исправлено 514 ошибок. Оба числа, вероятно, занижены.11921193Некоторые из наиболее заметных изменений:11941195- Если установлена переменная окружения [`PYTHONINSPECT`](https://python-all.ru/3.2/using/cmdline.html#envvar-PYTHONINSPECT), интерпретатор Python войдет в интерактивный режим после выполнения программы Python, как если бы Python был запущен с опцией [*-i*](https://python-all.ru/3.2/using/cmdline.html#cmdoption-i). Переменная окружения может быть установлена до запуска интерпретатора Python или может быть установлена самой программой Python в процессе выполнения.1196- Скрипт `regrtest.py` теперь предоставляет способ указать «все ресурсы, кроме *foo*». Имя ресурса, переданное опции [*-u*](https://python-all.ru/3.2/using/cmdline.html#cmdoption-u), теперь может начинаться с дефиса (`'-'`), что означает «удалить этот ресурс». Например, опция '`-uall,-bsddb`' может быть использована для включения всех ресурсов, кроме `bsddb`.1197- Инструменты, используемые для сборки документации, теперь работают в Cygwin, а также в Unix.1198- Опкод `SET_LINENO` был удален. В далеком прошлом этот опкод был нужен для генерации номеров строк в трассировке и поддержки функций трассировки (например, [`pdb`](https://python-all.ru/3.2/library/pdb.html#module-pdb)). Начиная с Python 1.5 номера строк в трассировке вычисляются с помощью другого механизма, который работает при «python -O». Для Python 2.3 Майкл Хадсон реализовал аналогичную схему для определения момента вызова функции трассировки, полностью устранив необходимость в `SET_LINENO`.11991200  Было бы трудно заметить какую-либо разницу в коде Python, за исключением небольшого ускорения при запуске Python без [*-O*](https://python-all.ru/3.2/using/cmdline.html#cmdoption-O).12011202  Расширения C, обращающиеся к полю `f_lineno` объектов фрейма, должны вместо этого вызывать `PyCode_Addr2Line(f->f_code, f->f_lasti)`. Это также позволит коду работать должным образом под «python -O» в более ранних версиях Python.12031204  Отличная новая возможность: функции трассировки теперь могут присваивать значение атрибуту `f_lineno` объектов фрейма, изменяя строку, которая будет выполнена следующей. В отладчик [`pdb`](https://python-all.ru/3.2/library/pdb.html#module-pdb) была добавлена команда `jump`, использующая эту новую возможность. (Реализовано Ричи Хиндлом.)12051206## Перенос на Python 2.312071208В этом разделе перечислены описанные ранее изменения, которые могут потребовать изменения кода:12091210- [`yield`](https://python-all.ru/3.2/reference/simple_stmts.html#yield) теперь является ключевым словом; если оно используется в коде как имя переменной, необходимо выбрать другое имя.1211- Для строк *X* и *Y* выражение `X in Y` теперь работает, если *X* длиннее одного символа.1212- Конструктор типа [`int()`](https://python-all.ru/3.2/library/functions.html#int) теперь будет возвращать длинное целое вместо того, чтобы вызывать [`OverflowError`](https://python-all.ru/3.2/library/exceptions.html#OverflowError), когда строка или число с плавающей запятой слишком велики, чтобы поместиться в целое.1213- Если у вас есть строки Unicode, содержащие 8-битные символы, вы должны объявить кодировку файла (UTF-8, Latin-1 или любую другую), добавив комментарий в начало файла. См. раздел [*PEP 263: Кодировки исходного кода*](https://python-all.ru/3.2/whatsnew/2.3.html#section-encodings) для получения дополнительной информации.1214- Вызов методов Tcl через `_tkinter` больше не возвращает только строки. Вместо этого, если Tcl возвращает другие объекты, они преобразуются в соответствующий эквивалент на Python, если таковой существует, или оборачиваются объектом `_tkinter.Tcl_Obj`, если эквивалента на Python нет.1215- Большие восьмеричные и шестнадцатеричные литералы, такие как `0xffffffff`, теперь вызывают [`FutureWarning`](https://python-all.ru/3.2/library/exceptions.html#FutureWarning). В настоящее время они хранятся как 32-битные числа и дают отрицательное значение, но в Python 2.4 они станут положительными длинными целыми.12161217  Есть несколько способов исправить это предупреждение. Если требуется положительное число, просто добавьте `L` в конец литерала. Если нужно получить 32-битное целое с установленными младшими битами и ранее использовалось выражение вроде `~(1 << 31)`, вероятно, понятнее всего начать со всеми установленными битами и сбросить нужные старшие биты. Например, чтобы сбросить только старший бит (бит 31), можно написать `0xffffffffL &~(1L<<31)`.1218- Больше нельзя отключить утверждения, присваивая значение `__debug__`.1219- Функция `setup()` из Distutils получила несколько новых именованных аргументов, таких как *depends*. Старые версии Distutils аварийно завершатся, если передать им неизвестные ключевые слова. Одно из решений – проверить наличие новой функции `get_distutil_options()` в `setup.py` и использовать новые ключевые слова только с версией Distutils, которая их поддерживает:12201221  ```python1222  from distutils import core12231224  kw = {'sources': 'foo.c', ...}1225  if hasattr(core, 'get_distutil_options'):1226      kw['depends'] = ['foo.h']1227  ext = Extension(**kw)1228  ```1229- Использование `None` в качестве имени переменной теперь будет вызывать [`SyntaxWarning`](https://python-all.ru/3.2/library/exceptions.html#SyntaxWarning) предупреждение.1230- Имена типов расширений, определённых модулями, входящими в состав Python, теперь содержат модуль и `'.'` перед именем типа.12311232## Благодарности12331234Автор хотел бы поблагодарить следующих людей за предложения, исправления и помощь с различными черновиками этой статьи: Jeff Bauer, Simon Brunning, Brett Cannon, Michael Chermside, Andrew Dalke, Scott David Daniels, Fred L. Drake, Jr., David Fraser, Kelly Gerber, Raymond Hettinger, Michael Hudson, Chris Lambert, Detlef Lannert, Martin von Löwis, Andrew MacIntyre, Lalo Martins, Chad Netzer, Gustavo Niemeyer, Neal Norwitz, Hans Nowak, Chris Reedy, Francesco Ricciardi, Vinay Sajip, Neil Schemenauer, Roman Suzi, Jason Tishler, Just van Rossum.1235