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

2.3.md

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

1> **Источник:** https://python-all.ru/3.8/whatsnew/2.3.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Что нового в Python 2.389**Автор**1011A.M. Kuchling1213В этой статье описываются новые возможности Python 2.3. Python 2.3 был выпущен 29 июля 2003 года.1415Основные темы Python 2.3 – доработка некоторых возможностей, добавленных в 2.2, внесение различных небольших, но полезных улучшений в ядро языка и расширение стандартной библиотеки. Новая объектная модель, введённая в предыдущей версии, получила 18 месяцев исправлений ошибок и оптимизаций, повысивших производительность классов нового стиля. Было добавлено несколько новых встроенных функций, таких как [`sum()`](https://python-all.ru/3.8/library/functions.html#sum) и [`enumerate()`](https://python-all.ru/3.8/library/functions.html#enumerate). Оператор [`in`](https://python-all.ru/3.8/reference/expressions.html#in) теперь можно использовать для поиска подстрок (например, `"ab" in "abc"` возвращает [`True`](https://python-all.ru/3.8/library/constants.html#True)).1617Некоторые из множества новых возможностей библиотеки включают логические типы, множества, кучи, типы даты/времени, возможность импортировать модули из ZIP-архивов, поддержку метаданных для долгожданного каталога Python, обновлённую версию IDLE, а также модули для журналирования сообщений, переноса текста, разбора CSV-файлов, обработки параметров командной строки, работы с базами данных BerkeleyDB… список новых и улучшенных модулей обширен.1819Эта статья не пытается дать полную спецификацию новых возможностей, а предоставляет удобный обзор. За полными подробностями следует обращаться к документации по Python 2.3, такой как «Справочник по библиотеке Python» и «Руководство по языку Python». Чтобы понять полную реализацию и обоснование дизайна, следует обратиться к PEP для конкретной новой возможности.2021## PEP 218: Стандартный тип данных «множество»2223Новый модуль `sets` содержит реализацию типа данных «множество». Класс `Set` предназначен для изменяемых множеств, в которые можно добавлять и удалять элементы. Класс `ImmutableSet` – для неизменяемых множеств, и экземпляры `ImmutableSet` поэтому могут использоваться в качестве ключей словаря. Множества построены на основе словарей, поэтому элементы множества должны быть хешируемыми.2425Вот простой пример:2627```python28>>> import sets29>>> S = sets.Set([1,2,3])30>>> S31Set([1, 2, 3])32>>> 1 in S33True34>>> 0 in S35False36>>> S.add(5)37>>> S.remove(3)38>>> S39Set([1, 2, 5])40>>>41```4243Объединение и пересечение множеств можно вычислить с помощью методов `union()` и `intersection()`; альтернативная запись использует побитовые операторы `&` и `|`. Изменяемые множества также имеют версии этих методов, изменяющие исходное множество: `union_update()` и `intersection_update()`.4445```python46>>> S1 = sets.Set([1,2,3])47>>> S2 = sets.Set([4,5,6])48>>> S1.union(S2)49Set([1, 2, 3, 4, 5, 6])50>>> S1 | S2                  # Альтернативная запись51Set([1, 2, 3, 4, 5, 6])52>>> S1.intersection(S2)53Set([])54>>> S1 & S2                  # Альтернативная запись55Set([])56>>> S1.union_update(S2)57>>> S158Set([1, 2, 3, 4, 5, 6])59>>>60```6162Также можно вычислить симметрическую разность двух множеств. Это множество всех элементов объединения, не входящих в пересечение. Другими словами, симметрическая разность содержит все элементы, которые есть ровно в одном из множеств. Опять же, существует альтернативная запись (`^`) и версия, изменяющая исходное множество, с неуклюжим названием `symmetric_difference_update()`.6364```python65>>> S1 = sets.Set([1,2,3,4])66>>> S2 = sets.Set([3,4,5,6])67>>> S1.symmetric_difference(S2)68Set([1, 2, 5, 6])69>>> S1 ^ S270Set([1, 2, 5, 6])71>>>72```7374Также существуют методы `issubset()` и `issuperset()` для проверки, является ли одно множество подмножеством или надмножеством другого:7576```python77>>> S1 = sets.Set([1,2,3])78>>> S2 = sets.Set([2,3])79>>> S2.issubset(S1)80True81>>> S1.issubset(S2)82False83>>> S1.issuperset(S2)84True85>>>86```8788> **См. также**89>90> **[**PEP 218**](https://python-all.ru/3.8/whatsnew/2.3.html) – Добавление встроенного типа объектов-множеств**91>92> PEP написан Грегом В. Уилсоном. Реализован Грегом В. Уилсоном, Алексом Мартелли и GvR.9394## PEP 255: Простые генераторы9596В Python 2.2 генераторы были добавлены как опциональная возможность, включаемая директивой `from __future__ import generators`. В версии 2.3 генераторы больше не нужно специально включать, и они теперь всегда доступны; это означает, что [`yield`](https://python-all.ru/3.8/reference/simple_stmts.html#yield) теперь всегда является ключевым словом. Остальная часть этого раздела является копией описания генераторов из документа «Что нового в Python 2.2»; если вы читали его, когда вышла версия 2.2, можете пропустить дальнейший текст.9798Вызовы функций в Python или C работают привычным образом. При вызове функция получает частное пространство имён, в котором создаются её локальные переменные. Когда функция достигает оператора [`return`](https://python-all.ru/3.8/reference/simple_stmts.html#return), локальные переменные уничтожаются, а полученное значение возвращается вызывающему. При последующем вызове той же функции она получит новый набор локальных переменных. Но что, если бы локальные переменные не выбрасывались при выходе из функции? Что, если бы можно было возобновить выполнение функции с того места, где она остановилась? Это и обеспечивают генераторы; их можно рассматривать как возобновляемые функции.99100Вот простейший пример функции-генератора:101102```python103def generate_ints(N):104    for i in range(N):105        yield i106```107108Для генераторов было введено новое ключевое слово [`yield`](https://python-all.ru/3.8/reference/simple_stmts.html#yield). Любая функция, содержащая оператор `yield`, является генераторной функцией; это обнаруживается компилятором байт-кода Python, который компилирует такую функцию особым образом.109110При вызове генераторной функции она не возвращает одно значение; вместо этого она возвращает объект-генератор, поддерживающий протокол итератора. При выполнении оператора [`yield`](https://python-all.ru/3.8/reference/simple_stmts.html#yield) генератор выводит значение `i`, аналогично оператору [`return`](https://python-all.ru/3.8/reference/simple_stmts.html#return). Большая разница между `yield` и `return` состоит в том, что при достижении `yield` состояние выполнения генератора приостанавливается, а локальные переменные сохраняются. При следующем вызове метода `.next()` генератора функция возобновит выполнение сразу после оператора `yield`. (По сложным причинам оператор `yield` не допускается внутри блока [`try`](https://python-all.ru/3.8/reference/compound_stmts.html#try) оператора `try``finally`; прочитайте [**PEP 255**](https://python-all.ru/3.8/whatsnew/2.3.html) для полного объяснения взаимодействия между `yield` и исключениями.)111112Вот пример использования генератора `generate_ints()`:113114```python115>>> gen = generate_ints(3)116>>> gen117<generator object at 0x8117f90>118>>> gen.next()1190120>>> gen.next()1211122>>> gen.next()1232124>>> gen.next()125Traceback (most recent call last):126  File "stdin", line 1, in ?127  File "stdin", line 2, in generate_ints128StopIteration129```130131Можно также написать `for i in generate_ints(5)` или `a,b,c = generate_ints(3)`.132133Внутри генераторной функции оператор [`return`](https://python-all.ru/3.8/reference/simple_stmts.html#return) может использоваться только без значения и сигнализирует об окончании последовательности значений; после этого генератор не может вернуть никаких дополнительных значений. `return` со значением, например `return 5`, является синтаксической ошибкой внутри генераторной функции. Конец результатов генератора также можно указать вручную, возбудив [`StopIteration`](https://python-all.ru/3.8/library/exceptions.html#StopIteration), или просто позволив потоку выполнения дойти до конца функции.134135Эффекта генераторов можно добиться вручную, написав собственный класс и сохранив все локальные переменные генератора как переменные экземпляра. Например, возврат списка целых чисел можно было бы реализовать, установив `self.count` в 0 и заставив метод [`next()`](https://python-all.ru/3.8/library/functions.html#next) увеличивать `self.count` и возвращать его. Однако для сколь-нибудь сложного генератора написание соответствующего класса было бы гораздо более запутанным. `Lib/test/test_generators.py` содержит ряд более интересных примеров. Самый простой из них реализует симметричный обход дерева с помощью рекурсивных генераторов.136137```python138# Рекурсивный генератор, порождающий листья дерева в порядке in-order.139def inorder(t):140    if t:141        for x in inorder(t.left):142            yield x143        yield t.label144        for x in inorder(t.right):145            yield x146```147148Два других примера в `Lib/test/test_generators.py` дают решения задачи о N ферзях (размещение N ферзей на шахматной доске N×N так, чтобы ни один ферзь не угрожал другому) и задачи об обходе коня (маршрут, по которому конь посещает каждую клетку доски N×N, не посещая ни одну клетку дважды).149150Идея генераторов пришла из других языков программирования, особенно Icon ([https://www.cs.arizona.edu/icon/](https://python-all.ru/3.8/whatsnew/2.3.html)), где идея генераторов является центральной. В Icon каждое выражение и вызов функции ведут себя как генератор. Один пример из «An Overview of the Icon Programming Language» по адресу [https://www.cs.arizona.edu/icon/docs/ipd266.htm](https://python-all.ru/3.8/whatsnew/2.3.html) даёт представление о том, как это выглядит:151152```python153sentence := "Store it in the neighboring harbor"154if (i := find("or", sentence)) > 5 then write(i)155```156157В Icon функция `find()` возвращает индексы, по которым найдена подстрока «or»: 3, 23, 33. В операторе [`if`](https://python-all.ru/3.8/reference/compound_stmts.html#if) переменной `i` сначала присваивается значение 3, но 3 меньше 5, поэтому сравнение не удаётся, и Icon повторяет попытку со вторым значением 23. 23 больше 5, поэтому теперь сравнение успешно, и код выводит на экран значение 23.158159Python не заходит так далеко, как Icon, в принятии генераторов в качестве центральной концепции. Генераторы считаются частью ядра языка Python, но их изучение или использование не является обязательным; если они не решают никаких проблем, их можно смело игнорировать. Одна новая особенность интерфейса Python по сравнению с Icon заключается в том, что состояние генератора представлено в виде конкретного объекта (итератора), который можно передавать другим функциям или хранить в структуре данных.160161> **См. также**162>163> **[**PEP 255**](https://python-all.ru/3.8/whatsnew/2.3.html) - Simple Generators**164>165> Авторы: Нил Шеменауэр, Тим Питерс, Магнус Ли Хетланд. Реализовано в основном Нилом Шеменауэром и Тимом Питерсом, с дополнительными исправлениями от команды Python Labs.166167## PEP 263: Кодировки исходного кода168169Файлы исходного кода Python теперь можно объявлять как файлы в различных кодировках символов. Кодировки объявляются путём включения специально отформатированного комментария в первую или вторую строку исходного файла. Например, файл в UTF-8 можно объявить с помощью:170171```python172#!/usr/bin/env python173# -*- coding: UTF-8 -*-174```175176Без такого объявления кодировки по умолчанию используется 7-битная ASCII. Выполнение или импорт модулей, содержащих строковые литералы с 8-битными символами и не имеющих объявления кодировки, приведёт к тому, что Python 2.3 сообщит о [`DeprecationWarning`](https://python-all.ru/3.8/library/exceptions.html#DeprecationWarning); в версии 2.4 это будет синтаксической ошибкой.177178Объявление кодировки влияет только на строковые литералы Unicode, которые будут преобразованы в Unicode с использованием указанной кодировки. Обратите внимание, что идентификаторы Python по-прежнему ограничены символами ASCII, поэтому нельзя использовать имена переменных, содержащие символы за пределами обычных буквенно-цифровых.179180> **См. также**181>182> **[**PEP 263**](https://python-all.ru/3.8/whatsnew/2.3.html) – Определение кодировок исходного кода Python**183>184> Авторы: Marc-André Lemburg и Martin von Löwis; реализовано Suzuki Hisao и Martin von Löwis.185186## PEP 273: Импорт модулей из ZIP-архивов187188Новый модуль [`zipimport`](https://python-all.ru/3.8/library/zipimport.html#module-zipimport) добавляет поддержку импорта модулей из архивов формата ZIP. Явно импортировать этот модуль не нужно; он будет импортирован автоматически, если имя файла ZIP-архива добавлено в `sys.path`. Например:189190```console191amk@nyman:~/src/python$ unzip -l /tmp/example.zip192Archive:  /tmp/example.zip193  Length     Date   Time    Name194 --------    ----   ----    ----195     8467  11-26-02 22:30   jwzthreading.py196 --------                   -------197     8467                   1 file198amk@nyman:~/src/python$ ./python199Python 2.3 (#1, Aug 1 2003, 19:54:32)200>>> import sys201>>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path202>>> import jwzthreading203>>> jwzthreading.__file__204'/tmp/example.zip/jwzthreading.py'205>>>206```207208Запись в `sys.path` теперь может быть именем файла ZIP-архива. ZIP-архив может содержать любые файлы, но импортировать можно только файлы с именами `*.py`, `*.pyc` или `*.pyo`. Если архив содержит только файлы `*.py`, Python не будет пытаться изменить архив, добавляя соответствующий файл `*.pyc`; это означает, что если ZIP-архив не содержит файлов `*.pyc`, импорт может быть довольно медленным.209210Также можно указать путь внутри архива, чтобы импортировать только из подкаталога; например, путь `/tmp/example.zip/lib/` будет импортировать только из подкаталога `lib/` внутри архива.211212> **См. также**213>214> **[**PEP 273**](https://python-all.ru/3.8/whatsnew/2.3.html) – Импорт модулей из Zip-архивов**215>216> Автор: James C. Ahlstrom, он же предоставил реализацию. Python 2.3 следует спецификации из [**PEP 273**](https://python-all.ru/3.8/whatsnew/2.3.html), но использует реализацию, написанную Just van Rossum, которая применяет хуки импорта, описанные в [**PEP 302**](https://python-all.ru/3.8/whatsnew/2.3.html). См. раздел [PEP 302: Новые хуки импорта](https://python-all.ru/3.8/whatsnew/2.3.html#section-pep302) для описания новых хуков импорта.217218## PEP 277: Поддержка имен файлов в Unicode для Windows NT219220В Windows NT, 2000 и XP система хранит имена файлов в виде строк Unicode. Традиционно Python представлял имена файлов как байтовые строки, что неудовлетворительно, так как делает некоторые имена файлов недоступными.221222Теперь Python позволяет использовать произвольные строки Unicode (в пределах ограничений файловой системы) для всех функций, ожидающих имена файлов, наиболее заметно – для встроенной функции [`open()`](https://python-all.ru/3.8/library/functions.html#open). Если в [`os.listdir()`](https://python-all.ru/3.8/library/os.html#os.listdir) передается строка Unicode, Python теперь возвращает список строк Unicode. Новая функция `os.getcwdu()` возвращает текущий каталог в виде строки Unicode.223224Байтовые строки по-прежнему работают как имена файлов, и в Windows Python будет прозрачно преобразовывать их в Unicode, используя кодировку `mbcs`.225226Другие системы также допускают строки Unicode в качестве имен файлов, но преобразуют их в байтовые строки перед передачей системе, что может вызвать [`UnicodeError`](https://python-all.ru/3.8/library/exceptions.html#UnicodeError). Приложения могут проверить, поддерживаются ли произвольные строки Unicode в качестве имен файлов, проверив [`os.path.supports_unicode_filenames`](https://python-all.ru/3.8/library/os.path.html#os.path.supports_unicode_filenames), логическое значение.227228В MacOS [`os.listdir()`](https://python-all.ru/3.8/library/os.html#os.listdir) теперь может возвращать имена файлов в Unicode.229230> **См. также**231>232> **[**PEP 277**](https://python-all.ru/3.8/whatsnew/2.3.html) – Поддержка имен файлов в Unicode для Windows NT**233>234> Автор: Neil Hodgson; реализовано Neil Hodgson, Martin von Löwis и Mark Hammond.235236## PEP 278: Универсальная поддержка символов новой строки237238Три основные операционные системы, используемые сегодня: Microsoft Windows, Apple Macintosh OS и различные производные Unix. Небольшое раздражение при кросс-платформенной работе заключается в том, что эти три платформы используют разные символы для обозначения концов строк в текстовых файлах. Unix использует перевод строки (символ ASCII 10), MacOS – возврат каретки (символ ASCII 13), а Windows – двухсимвольную последовательность: возврат каретки и перевод строки.239240Файловые объекты Python теперь могут поддерживать соглашения о конце строк, отличные от того, которое используется платформой, на которой выполняется Python. Открытие файла с режимом `'U'` или `'rU'` откроет файл для чтения в режиме [универсальных символов новой строки](https://python-all.ru/3.8/glossary.html#term-universal-newlines). Все три соглашения о конце строк будут преобразованы в `'\n'` в строках, возвращаемых различными методами файлов, такими как `read()` и [`readline()`](https://python-all.ru/3.8/library/readline.html#module-readline).241242Поддержка универсальных символов новой строки также используется при импорте модулей и при выполнении файла с помощью функции `execfile()`. Это означает, что модули Python могут быть общими для всех трех операционных систем без необходимости преобразования концов строк.243244Эту функцию можно отключить при компиляции Python, указав флаг `--without-universal-newlines` при запуске сценария **configure**.245246> **См. также**247>248> **[**PEP 278**](https://python-all.ru/3.8/whatsnew/2.3.html) – Универсальная поддержка символов новой строки**249>250> Автор и разработчик: Jack Jansen.251252## PEP 279: enumerate()253254Новая встроенная функция [`enumerate()`](https://python-all.ru/3.8/library/functions.html#enumerate) сделает некоторые циклы немного понятнее. `enumerate(thing)`, где *thing* – это либо итератор, либо последовательность, возвращает итератор, который будет возвращать `(0, thing[0])`, `(1, thing[1])`, `(2, thing[2])` и так далее.255256Типичный способ изменить каждый элемент списка выглядит так:257258```python259for i in range(len(L)):260    item = L[i]261    # ... вычислить результат на основе элемента ...262    L[i] = result263```264265Это можно переписать с помощью [`enumerate()`](https://python-all.ru/3.8/library/functions.html#enumerate) следующим образом:266267```python268for i, item in enumerate(L):269    # ... вычислить результат на основе элемента ...270    L[i] = result271```272273> **См. также**274>275> **[**PEP 279**](https://python-all.ru/3.8/whatsnew/2.3.html) – Встроенная функция enumerate()**276>277> Автор и разработчик: Raymond D. Hettinger.278279## PEP 282: Пакет logging280281Стандартный пакет для ведения журналов, [`logging`](https://python-all.ru/3.8/library/logging.html#module-logging), был добавлен в Python 2.3. Он предоставляет мощный и гибкий механизм для создания записей журнала, которые затем можно фильтровать и обрабатывать различными способами. Для управления поведением журналирования программы можно использовать файл конфигурации в стандартном формате. Python включает обработчики, которые записывают записи журнала в стандартный поток ошибок, в файл или сокет, отправляют их в системный журнал или даже по электронной почте на конкретный адрес; конечно, можно также написать свои собственные классы обработчиков.282283Класс `Logger` является основным. Большинство кода приложения будет работать с одним или несколькими объектами `Logger`, каждый из которых используется определенной подсистемой приложения. Каждый `Logger` идентифицируется по имени, и имена организованы в иерархию с использованием `.` в качестве разделителя компонентов. Например, могут быть экземпляры `Logger` с именами `server`, `server.auth` и `server.network`. Последние два экземпляра находятся ниже `server` в иерархии. Это означает, что если увеличить подробность для `server` или направить сообщения `server` в другой обработчик, изменения также применятся к записям, регистрируемым в `server.auth` и `server.network`. Также есть корневой `Logger`, который является родителем всех остальных регистраторов.284285Для простого использования пакет [`logging`](https://python-all.ru/3.8/library/logging.html#module-logging) содержит несколько удобных функций, которые всегда используют корневой журнал:286287```python288import logging289290logging.debug('Debugging information')291logging.info('Informational message')292logging.warning('Warning:config file %s not found', 'server.conf')293logging.error('Error occurred')294logging.critical('Critical error -- shutting down')295```296297Это даёт следующий вывод:298299```python300WARNING:root:Warning:config file server.conf not found301ERROR:root:Error occurred302CRITICAL:root:Critical error -- shutting down303```304305В конфигурации по умолчанию информационные и отладочные сообщения подавляются, а вывод направляется в стандартный поток ошибок. Включить отображение информационных и отладочных сообщений можно, вызвав метод `setLevel()` корневого регистратора.306307Обратите внимание на использование операторов форматирования строк в вызове `warning()`; все функции для регистрации сообщений принимают аргументы `(msg, arg1, arg2, ...)` и регистрируют строку, полученную в результате `msg % (arg1, arg2, ...)`.308309Существует также функция `exception()`, которая записывает последнюю трассировку. Любая другая функция также запишет трассировку, если указать истинное значение для ключевого аргумента *exc\_info*.310311```python312def f():313    try:    1/0314    except: logging.exception('Problem recorded')315316f()317```318319Это даёт следующий вывод:320321```python322ERROR:root:Problem recorded323Traceback (most recent call last):324  File "t.py", line 6, in f325    1/0326ZeroDivisionError: integer division or modulo by zero327```328329Немного более продвинутые программы используют регистратор, отличный от корневого. Функция `getLogger(name)` используется для получения конкретного регистратора, создавая его, если он ещё не существует. `getLogger(None)` возвращает корневой регистратор.330331```python332log = logging.getLogger('server')333 ...334log.info('Listening on port %i', port)335 ...336log.critical('Disk full')337 ...338```339340Записи журнала обычно распространяются вверх по иерархии, поэтому сообщение, записанное в `server.auth`, также видно `server` и `root`, но `Logger` может предотвратить это, установив для своего атрибута `propagate` значение [`False`](https://python-all.ru/3.8/library/constants.html#False).341342Пакет [`logging`](https://python-all.ru/3.8/library/logging.html#module-logging) предоставляет и другие классы, которые можно настраивать. Когда экземпляру `Logger` поручается записать сообщение, он создаёт экземпляр `LogRecord`, который отправляется любому количеству различных экземпляров `Handler`. К регистраторам и обработчикам также можно прикрепить список фильтров; каждый фильтр может привести к игнорированию `LogRecord` или изменить запись перед её передачей. При окончательном выводе экземпляры `LogRecord` преобразуются в текст классом `Formatter`. Все эти классы можно заменить на собственные, написанные вами классы.343344Благодаря всем этим возможностям пакет [`logging`](https://python-all.ru/3.8/library/logging.html#module-logging) обеспечивает достаточную гибкость даже для самых сложных приложений. Это лишь неполный обзор его возможностей; пожалуйста, обратитесь к справочной документации пакета для получения всех подробностей. Также полезно будет прочитать [**PEP 282**](https://python-all.ru/3.8/whatsnew/2.3.html).345346> **См. также**347>348> **[**PEP 282**](https://python-all.ru/3.8/whatsnew/2.3.html) – Система логирования**349>350> Написано Vinay Sajip и Trent Mick; реализовано Vinay Sajip.351352## PEP 285: Логический тип353354Логический тип был добавлен в Python 2.3. В модуль `__builtin__` были добавлены две новые константы: [`True`](https://python-all.ru/3.8/library/constants.html#True) и [`False`](https://python-all.ru/3.8/library/constants.html#False). (Константы [`True`](https://python-all.ru/3.8/library/constants.html#True) и [`False`](https://python-all.ru/3.8/library/constants.html#False) были добавлены во встроенные объекты в Python 2.2.1, но в версии 2.2.1 они просто установлены в целочисленные значения 1 и 0 и не являются отдельным типом.)355356Объект типа для этого нового типа называется [`bool`](https://python-all.ru/3.8/library/functions.html#bool); его конструктор принимает любое значение Python и преобразует его в [`True`](https://python-all.ru/3.8/library/constants.html#True) или [`False`](https://python-all.ru/3.8/library/constants.html#False).357358```python359>>> bool(1)360True361>>> bool(0)362False363>>> bool([])364False365>>> bool( (1,) )366True367```368369Большинство модулей стандартной библиотеки и встроенных функций были изменены, чтобы возвращать логические значения.370371```python372>>> obj = []373>>> hasattr(obj, 'append')374True375>>> isinstance(obj, list)376True377>>> isinstance(obj, tuple)378False379```380381Логический тип Python был добавлен с главной целью – сделать код понятнее. Например, если вы читаете функцию и встречаете инструкцию `return 1`, вы можете задаться вопросом, представляет ли `1` логическое истинное значение, индекс или коэффициент, умножающий некоторое другое значение. Однако если инструкция – `return True`, смысл возвращаемого значения совершенно ясен.382383Логический тип Python был добавлен *не* для строгой проверки типов. Очень строгий язык, такой как Pascal, также не позволил бы выполнять арифметику с логическими значениями и потребовал бы, чтобы выражение в инструкции [`if`](https://python-all.ru/3.8/reference/compound_stmts.html#if) всегда вычислялось в логический результат. Python не настолько строг и никогда не будет, как [**PEP 285**](https://python-all.ru/3.8/whatsnew/2.3.html) явно говорит. Это означает, что вы по-прежнему можете использовать любое выражение в инструкции `if`, даже те, которые вычисляются в список, кортеж или какой-либо случайный объект. Логический тип является подклассом класса [`int`](https://python-all.ru/3.8/library/functions.html#int), поэтому арифметика с логическими значениями всё ещё работает.384385```python386>>> True + 13872388>>> False + 13891390>>> False * 753910392>>> True * 7539375394```395396Если подвести итог [`True`](https://python-all.ru/3.8/library/constants.html#True) и [`False`](https://python-all.ru/3.8/library/constants.html#False) одной фразой: это альтернативные способы записи целочисленных значений 1 и 0, с единственным отличием, что [`str()`](https://python-all.ru/3.8/library/stdtypes.html#str) и [`repr()`](https://python-all.ru/3.8/library/functions.html#repr) возвращают строки `'True'` и `'False'` вместо `'1'` и `'0'`.397398> **См. также**399>400> **[**PEP 285**](https://python-all.ru/3.8/whatsnew/2.3.html) – Добавление логического типа**401>402> Автор и разработчик: GvR.403404## PEP 293: Колбэки обработки ошибок кодеков405406При кодировании строки Unicode в байтовую строку могут встретиться символы, которые невозможно закодировать. До сих пор Python позволял указывать обработку ошибок как «strict» (вызывается [`UnicodeError`](https://python-all.ru/3.8/library/exceptions.html#UnicodeError)), «ignore» (пропуск символа) или «replace» (использование вопросительного знака в выходной строке), при этом поведением по умолчанию является «strict». Может быть желательным указать альтернативную обработку таких ошибок, например, вставку ссылки на символ XML или ссылки на сущность HTML в преобразованную строку.407408Теперь Python имеет гибкую платформу для добавления различных стратегий обработки. Новые обработчики ошибок можно добавить с помощью [`codecs.register_error()`](https://python-all.ru/3.8/library/codecs.html#codecs.register_error), и после этого кодеки могут получить доступ к обработчику ошибок через [`codecs.lookup_error()`](https://python-all.ru/3.8/library/codecs.html#codecs.lookup_error). Эквивалентный C API был добавлен для кодеков, написанных на C. Обработчик ошибок получает необходимую информацию о состоянии, такую как преобразуемая строка, позиция в строке, где была обнаружена ошибка, и целевая кодировка. Затем обработчик может либо вызвать исключение, либо вернуть строку замены.409410С помощью этой платформы были реализованы два дополнительных обработчика ошибок: «backslashreplace» использует экранирование обратной косой чертой Python для представления незакодируемых символов, а «xmlcharrefreplace» генерирует ссылки на символы XML.411412> **См. также**413>414> **[**PEP 293**](https://python-all.ru/3.8/whatsnew/2.3.html) – Колбэки обработки ошибок кодеков**415>416> Автор и разработчик: Walter Dörwald.417418## PEP 301: Индекс пакетов и метаданные для Distutils419420Поддержка долгожданного каталога Python впервые появляется в версии 2.3.421422Сердцем каталога является новая команда Distutils **register**. Запуск `python setup.py register` собирает метаданные, описывающие пакет, такие как его имя, версию, сопровождающего, описание и т.д., и отправляет их на центральный сервер каталога. Полученный каталог доступен по адресу [https://pypi.org](https://python-all.ru/3.8/whatsnew/2.3.html).423424Чтобы сделать каталог немного более полезным, был добавлен новый необязательный ключевой аргумент *classifiers* в функцию Distutils `setup()`. Можно указать список строк в стиле [Trove](https://python-all.ru/3.8/whatsnew/2.3.html), чтобы помочь классифицировать программное обеспечение.425426Вот пример `setup.py` с классификаторами, написанный для совместимости со старыми версиями Distutils:427428```python429from distutils import core430kw = {'name': "Quixote",431      'version': "0.5.1",432      'description': "A highly Pythonic Web application framework",433      # ...434      }435436if (hasattr(core, 'setup_keywords') and437    'classifiers' in core.setup_keywords):438    kw['classifiers'] = \439        ['Topic :: Internet :: WWW/HTTP :: Dynamic Content',440         'Environment :: No Input/Output (Daemon)',441         'Intended Audience :: Developers'],442443core.setup(**kw)444```445446Полный список классификаторов можно получить, запустив `python setup.py register --list-classifiers`.447448> **См. также**449>450> **[**PEP 301**](https://python-all.ru/3.8/whatsnew/2.3.html) – Индекс пакетов и метаданные для Distutils**451>452> Автор и разработчик: Richard Jones.453454## PEP 302: Новые хуки импорта455456Хотя можно было создавать собственные хуки импорта с момента появления модуля `ihooks` в Python 1.3, никто не был им полностью доволен, потому что написание новых хуков импорта было сложным и запутанным. Были разные предложения, такие как модули `imputil` и `iu`, но ни одно из них не получило широкого признания, и ни одно из них не было легко использовать из кода на C.457458[**PEP 302**](https://python-all.ru/3.8/whatsnew/2.3.html) заимствует идеи у своих предшественников, особенно у модуля `iu` Гордона МакМиллана. В модуль [`sys`](https://python-all.ru/3.8/library/sys.html#module-sys) добавлены три новых элемента:459460- `sys.path_hooks` – это список вызываемых объектов; чаще всего это будут классы. Каждый вызываемый объект принимает строку, содержащую путь, и либо возвращает объект импортёра, который будет обрабатывать импорт из этого пути, либо возбуждает исключение [`ImportError`](https://python-all.ru/3.8/library/exceptions.html#ImportError), если не может обработать этот путь.461- `sys.path_importer_cache` кеширует объекты импортёров для каждого пути, поэтому `sys.path_hooks` нужно будет обойти только один раз для каждого пути.462- `sys.meta_path` – это список объектов импортёров, которые будут просматриваться до проверки `sys.path`. Этот список изначально пуст, но пользовательский код может добавлять в него объекты. Дополнительные встроенные и замороженные модули могут быть импортированы объектом, добавленным в этот список.463464Объекты импортёров должны иметь единственный метод `find_module(fullname, path=None)`. *fullname* будет именем модуля или пакета, например `string` или `distutils.core`. `find_module()` должен возвращать объект загрузчика, который имеет единственный метод `load_module(fullname)`, создающий и возвращающий соответствующий объект модуля.465466Псевдокод новой логики импорта в Python выглядит примерно так (немного упрощён; полные подробности см. в [**PEP 302**](https://python-all.ru/3.8/whatsnew/2.3.html)):467468```python469for mp in sys.meta_path:470    loader = mp(fullname)471    if loader is not None:472        <module> = loader.load_module(fullname)473474for path in sys.path:475    for hook in sys.path_hooks:476        try:477            importer = hook(path)478        except ImportError:479            # ImportError, поэтому попробуем другие перехватчики путей480            pass481        else:482            loader = importer.find_module(fullname)483            <module> = loader.load_module(fullname)484485# Не найдено!486raise ImportError487```488489> **См. также**490>491> **[**PEP 302**](https://python-all.ru/3.8/whatsnew/2.3.html) – новые хуки импорта**492>493> Автор: Just van Rossum и Paul Moore. Реализовано Just van Rossum.494495## PEP 305: Файлы с разделителями-запятыми496497Файлы с разделителями-запятыми – это формат, часто используемый для экспорта данных из баз данных и электронных таблиц. В Python 2.3 добавлен синтаксический анализатор таких файлов.498499Формат с разделителями-запятыми на первый взгляд обманчиво прост:500501```python502Costs,150,200,3.95503```504505Прочитать строку и вызвать `line.split(',')`: что может быть проще? Но если добавить строковые данные, которые могут содержать запятые, всё становится сложнее:506507```python508"Costs",150,200,3.95,"Includes taxes, shipping, and sundry items"509```510511Большое уродливое регулярное выражение может это разобрать, но использовать новый пакет [`csv`](https://python-all.ru/3.8/library/csv.html#module-csv) гораздо проще:512513```python514import csv515516input = open('datafile', 'rb')517reader = csv.reader(input)518for line in reader:519    print line520```521522Функция `reader()` принимает ряд различных опций. Разделитель полей не ограничивается запятой – его можно заменить на любой символ, и то же самое касается символов кавычек и окончания строки.523524Можно определить и зарегистрировать различные диалекты файлов с разделителями-запятыми; в настоящее время существует два диалекта, оба используемых Microsoft Excel. Отдельный класс [`csv.writer`](https://python-all.ru/3.8/library/csv.html#csv.writer) будет генерировать файлы с разделителями-запятыми из последовательности кортежей или списков, заключая в кавычки строки, содержащие разделитель.525526> **См. также**527>528> **[**PEP 305**](https://python-all.ru/3.8/whatsnew/2.3.html) - API для CSV-файлов**529>530> Авторы и разработчики: Kevin Altis, Dave Cole, Andrew McNamara, Skip Montanaro, Cliff Wells.531532## PEP 307: Улучшения pickle533534Модули [`pickle`](https://python-all.ru/3.8/library/pickle.html#module-pickle) и `cPickle` получили некоторое внимание в ходе цикла разработки 2.3. В 2.2 классы нового стиля можно было сериализовать без труда, но они сериализовались не очень компактно; [**PEP 307**](https://python-all.ru/3.8/whatsnew/2.3.html) приводит тривиальный пример, где класс нового стиля даёт сериализованную строку в три раза длиннее, чем для классического класса.535536Решением стало изобретение нового протокола pickle. Функция [`pickle.dumps()`](https://python-all.ru/3.8/library/pickle.html#pickle.dumps) уже давно поддерживает флаг текст/бинарный. В 2.3 этот флаг переопределён с логического на целое число: 0 – старый текстовый формат pickle, 1 – старый бинарный формат, а 2 – новый формат, специфичный для 2.3. Новая константа [`pickle.HIGHEST_PROTOCOL`](https://python-all.ru/3.8/library/pickle.html#pickle.HIGHEST_PROTOCOL) может использоваться для выбора самого нового доступного протокола.537538Десериализация больше не считается безопасной операцией. [`pickle`](https://python-all.ru/3.8/library/pickle.html#module-pickle) в версии 2.2 предоставлял хуки для предотвращения десериализации небезопасных классов (в частности, атрибут `__safe_for_unpickling__`), но этот код никогда не проверялся, и поэтому в 2.3 он полностью удалён. Не следует десериализовать недоверенные данные в любой версии Python.539540Чтобы снизить накладные расходы на сериализацию классов нового стиля, был добавлен новый интерфейс для настройки сериализации с использованием трёх специальных методов: [`__getstate__()`](https://python-all.ru/3.8/library/pickle.html#object.__getstate__), [`__setstate__()`](https://python-all.ru/3.8/library/pickle.html#object.__setstate__) и [`__getnewargs__()`](https://python-all.ru/3.8/library/pickle.html#object.__getnewargs__). Полную семантику этих методов см. в [**PEP 307**](https://python-all.ru/3.8/whatsnew/2.3.html).541542Для ещё большего сжатия pickle теперь можно использовать целочисленные коды вместо длинных строк для идентификации сериализованных классов. Python Software Foundation будет поддерживать список стандартизированных кодов; также существует диапазон кодов, зарезервированных для частного использования. В настоящее время коды не определены.543544> **См. также**545>546> **[**PEP 307**](https://python-all.ru/3.8/whatsnew/2.3.html) – расширения протокола pickle**547>548> Авторы и разработчики: Guido van Rossum и Tim Peters.549550## Расширенные срезы551552Начиная с Python 1.4 синтаксис срезов поддерживает необязательный третий аргумент «шаг». Например, всё это допустимый синтаксис Python: `L[1:10:2]`, `L[:-1:1]`, `L[::-1]`. Это было добавлено в Python по запросу разработчиков Numerical Python, которые широко используют третий аргумент. Однако встроенные типы последовательностей Python – списки, кортежи и строки – никогда не поддерживали эту возможность, возбуждая [`TypeError`](https://python-all.ru/3.8/library/exceptions.html#TypeError) при попытке её использовать. Майкл Хадсон внёс патч для исправления этого недостатка.553554Например, теперь можно легко извлечь элементы списка с чётными индексами:555556```python557>>> L = range(10)558>>> L[::2]559[0, 2, 4, 6, 8]560```561562Отрицательные значения также работают, чтобы создать копию того же списка в обратном порядке:563564```python565>>> L[::-1]566[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]567```568569Это также работает для кортежей, массивов и строк:570571```python572>>> s='abcd'573>>> s[::2]574'ac'575>>> s[::-1]576'dcba'577```578579Если у вас есть изменяемая последовательность, например список или массив, вы можете присваивать значение расширенному срезу или удалять его, но есть некоторые различия между присваиванием расширенным и обычным срезам. Присваивание обычному срезу может использоваться для изменения длины последовательности:580581```python582>>> a = range(3)583>>> a584[0, 1, 2]585>>> a[1:3] = [4, 5, 6]586>>> a587[0, 4, 5, 6]588```589590Расширенные срезы не настолько гибки. При присваивании расширенному срезу список в правой части оператора должен содержать то же количество элементов, что и заменяемый срез:591592```python593>>> a = range(4)594>>> a595[0, 1, 2, 3]596>>> a[::2]597[0, 2]598>>> a[::2] = [0, -1]599>>> a600[0, 1, -1, 3]601>>> a[::2] = [0,1,2]602Traceback (most recent call last):603  File "<stdin>", line 1, in ?604ValueError: attempt to assign sequence of size 3 to extended slice of size 2605```606607Удаление выполняется проще:608609```python610>>> a = range(4)611>>> a612[0, 1, 2, 3]613>>> a[::2]614[0, 2]615>>> del a[::2]616>>> a617[1, 3]618```619620Теперь также можно передавать объекты срезов методам [`__getitem__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__getitem__) встроенных последовательностей:621622```python623>>> range(10).__getitem__(slice(0, 5, 2))624[0, 2, 4]625```626627Или использовать объекты срезов непосредственно в индексации:628629```python630>>> range(10)[slice(0, 5, 2)]631[0, 2, 4]632```633634Чтобы упростить реализацию последовательностей, поддерживающих расширенную нарезку, объекты срезов теперь имеют метод `indices(length)`, который, зная длину последовательности, возвращает кортеж `(start, stop, step)`, который можно напрямую передать [`range()`](https://python-all.ru/3.8/library/stdtypes.html#range). `indices()` обрабатывает пропущенные и выходящие за границы индексы так же, как обычные срезы (и эта безобидная фраза скрывает множество запутанных деталей!). Метод предназначен для использования следующим образом:635636```python637class FakeSeq:638    ...639    def calc_item(self, i):640        ...641    def __getitem__(self, item):642        if isinstance(item, slice):643            indices = item.indices(len(self))644            return FakeSeq([self.calc_item(i) for i in range(*indices)])645        else:646            return self.calc_item(i)647```648649Из этого примера также видно, что встроенный объект [`slice`](https://python-all.ru/3.8/library/functions.html#slice) теперь является объектом типа для типа среза и больше не является функцией. Это соответствует Python 2.2, где [`int`](https://python-all.ru/3.8/library/functions.html#int), [`str`](https://python-all.ru/3.8/library/stdtypes.html#str) и т.д. претерпели те же изменения.650651## Прочие изменения языка652653Ниже перечислены все изменения, которые Python 2.3 вносит в ядро языка Python.654655- Оператор [`yield`](https://python-all.ru/3.8/reference/simple_stmts.html#yield) теперь всегда является ключевым словом, как описано в разделе [PEP 255: Simple Generators](https://python-all.ru/3.8/whatsnew/2.3.html#section-generators) этого документа.656- Добавлена новая встроенная функция [`enumerate()`](https://python-all.ru/3.8/library/functions.html#enumerate), как описано в разделе [PEP 279: enumerate()](https://python-all.ru/3.8/whatsnew/2.3.html#section-enumerate) этого документа.657- Добавлены две новые константы, [`True`](https://python-all.ru/3.8/library/constants.html#True) и [`False`](https://python-all.ru/3.8/library/constants.html#False), вместе со встроенным типом [`bool`](https://python-all.ru/3.8/library/functions.html#bool), как описано в разделе [PEP 285: A Boolean Type](https://python-all.ru/3.8/whatsnew/2.3.html#section-bool) этого документа.658- Конструктор типа [`int()`](https://python-all.ru/3.8/library/functions.html#int) теперь будет возвращать длинное целое вместо возбуждения [`OverflowError`](https://python-all.ru/3.8/library/exceptions.html#OverflowError), когда строка или число с плавающей запятой слишком велики для целого числа. Это может привести к парадоксальному результату, что `isinstance(int(expression), int)` ложно, но на практике это вряд ли вызовет проблемы.659- Встроенные типы теперь поддерживают расширенный синтаксис срезов, как описано в разделе [Extended Slices](https://python-all.ru/3.8/whatsnew/2.3.html#section-slices) этого документа.660- Новая встроенная функция `sum(iterable, start=0)` суммирует числовые элементы итерируемого объекта и возвращает их сумму. [`sum()`](https://python-all.ru/3.8/library/functions.html#sum) принимает только числа, то есть её нельзя использовать для конкатенации строк. (Автор: Alex Martelli.)661- `list.insert(pos, value)` ранее вставлял *value* в начало списка, когда *pos* был отрицательным. Теперь поведение изменено для согласованности с индексацией срезов, поэтому когда *pos* равно -1, значение вставляется перед последним элементом и так далее.662- `list.index(value)`, который ищет *value* в списке и возвращает его индекс, теперь принимает необязательные аргументы *start* и *stop*, чтобы ограничить поиск только частью списка.663- Словари имеют новый метод `pop(key[, *default*])`, который возвращает значение, соответствующее *key*, и удаляет эту пару ключ/значение из словаря. Если запрошенный ключ отсутствует в словаре, *default* возвращается, если он указан, и вызывается [`KeyError`](https://python-all.ru/3.8/library/exceptions.html#KeyError), если нет.664665  ```python666  >>> d = {1:2}667  >>> d668  {1: 2}669  >>> d.pop(4)670  Traceback (most recent call last):671    File "stdin", line 1, in ?672  KeyError: 4673  >>> d.pop(1)674  2675  >>> d.pop(1)676  Traceback (most recent call last):677    File "stdin", line 1, in ?678  KeyError: 'pop(): dictionary is empty'679  >>> d680  {}681  >>>682  ```683684  Также есть новый метод класса `dict.fromkeys(iterable, value)`, который создаёт словарь с ключами из предоставленного итератора *iterable* и всеми значениями, установленными в *value*, по умолчанию `None`.685686  (Патчи предоставлены Raymond Hettinger.)687688  Кроме того, конструктор [`dict()`](https://python-all.ru/3.8/library/stdtypes.html#dict) теперь принимает именованные аргументы для упрощения создания небольших словарей:689690  ```python691  >>> dict(red=1, blue=2, green=3, black=4)692  {'blue': 2, 'black': 4, 'green': 3, 'red': 1}693  ```694695  (Автор: Just van Rossum.)696- Оператор [`assert`](https://python-all.ru/3.8/reference/simple_stmts.html#assert) больше не проверяет флаг `__debug__`, поэтому отключить утверждения присваиванием `__debug__` больше нельзя. Запуск Python с ключом [`-O`](https://python-all.ru/3.8/using/cmdline.html#cmdoption-o) по-прежнему будет генерировать код, который не выполняет никаких утверждений.697- Большинство объектов типа теперь вызываемы, поэтому вы можете использовать их для создания новых объектов, таких как функции, классы и модули. (Это означает, что модуль `new` может быть объявлен устаревшим в будущей версии Python, поскольку теперь можно использовать объекты типа, доступные в модуле [`types`](https://python-all.ru/3.8/library/types.html#module-types).) Например, можно создать новый объект модуля следующим кодом:698699  ```python700  >>> import types701  >>> m = types.ModuleType('abc','docstring')702  >>> m703  <module 'abc' (built-in)>704  >>> m.__doc__705  'docstring'706  ```707- Добавлено новое предупреждение [`PendingDeprecationWarning`](https://python-all.ru/3.8/library/exceptions.html#PendingDeprecationWarning) для указания функций, которые находятся в процессе устаревания. Предупреждение по умолчанию *не* будет выводиться. Чтобы проверить использование функций, которые будут устаревать в будущем, укажите [`-Walways::PendingDeprecationWarning::`](https://python-all.ru/3.8/using/cmdline.html#cmdoption-w) в командной строке или используйте [`warnings.filterwarnings()`](https://python-all.ru/3.8/library/warnings.html#warnings.filterwarnings).708- Начался процесс устаревания исключений на основе строк, как в `raise "Error occurred"`. Возбуждение строки теперь вызывает [`PendingDeprecationWarning`](https://python-all.ru/3.8/library/exceptions.html#PendingDeprecationWarning).709- Использование `None` в качестве имени переменной теперь приведёт к предупреждению [`SyntaxWarning`](https://python-all.ru/3.8/library/exceptions.html#SyntaxWarning). В будущей версии Python `None` может наконец стать ключевым словом.710- Метод `xreadlines()` файловых объектов, введённый в Python 2.1, больше не нужен, поскольку файлы теперь ведут себя как собственный итератор. `xreadlines()` изначально был введён как более быстрый способ перебора всех строк в файле, но теперь можно просто написать `for line in file_obj`. Файловые объекты также имеют новый атрибут `encoding` только для чтения, который указывает кодировку, используемую файлом; строки Unicode, записываемые в файл, будут автоматически преобразованы в байты с использованием указанной кодировки.711- Порядок разрешения методов, используемый классами нового стиля, изменился, хотя разницу можно заметить только при очень сложной иерархии наследования. Классы старого стиля это изменение не затрагивает. В Python 2.2 изначально использовалась топологическая сортировка предков класса, но в 2.3 теперь применяется алгоритм C3, описанный в статье [«A Monotonic Superclass Linearization for Dylan»](https://python-all.ru/3.8/whatsnew/2.3.html). Чтобы понять мотивацию этого изменения, прочитайте статью Микеле Симонато [«Python 2.3 Method Resolution Order»](https://python-all.ru/3.8/whatsnew/2.3.html) или ознакомьтесь с обсуждением в python-dev, начиная с сообщения по адресу [https://mail.python.org/pipermail/python-dev/2002-October/029035.html](https://python-all.ru/3.8/whatsnew/2.3.html). Самуэле Педрони первым указал на проблему и реализовал исправление, закодировав алгоритм C3.712- Python выполняет многопоточные программы, переключаясь между потоками после выполнения N байткодов. Значение по умолчанию для N было увеличено с 10 до 100 байткодов, что ускоряет однопоточные приложения за счёт снижения накладных расходов на переключение. Некоторые многопоточные приложения могут страдать от более медленного времени отклика, но это легко исправить, установив предел обратно на меньшее число с помощью `sys.setcheckinterval(N)`. Предел можно получить с помощью новой функции [`sys.getcheckinterval()`](https://python-all.ru/3.8/library/sys.html#sys.getcheckinterval).713- Одно незначительное, но далеко идущее изменение заключается в том, что имена типов расширений, определённых модулями, входящими в состав Python, теперь содержат имя модуля и `'.'` в перед именем типа. Например, в Python 2.2, если вы создали сокет и вывели его `__class__`, вы получили бы такой вывод:714715  ```python716  >>> s = socket.socket()717  >>> s.__class__718  <type 'socket'>719  ```720721  В 2.3 вы получите это:722723  ```python724  >>> s.__class__725  <type '_socket.socket'>726  ```727- Одно из замеченных несоответствий между классами старого и нового стиля было устранено: теперь можно присваивать значения атрибутам [`__name__`](https://python-all.ru/3.8/library/stdtypes.html#definition.__name__) и [`__bases__`](https://python-all.ru/3.8/library/stdtypes.html#class.__bases__) классов нового стиля. Существуют некоторые ограничения на то, что можно присваивать [`__bases__`](https://python-all.ru/3.8/library/stdtypes.html#class.__bases__), аналогичные тем, что относятся к присваиванию атрибуту [`__class__`](https://python-all.ru/3.8/library/stdtypes.html#instance.__class__) экземпляра.728729### Изменения строк730731- Оператор [`in`](https://python-all.ru/3.8/reference/expressions.html#in) теперь работает со строками по-новому. Раньше при вычислении `X in Y`, где *X* и *Y* – строки, *X* могло быть только одним символом. Теперь это изменилось: *X* может быть строкой любой длины, и `X in Y` возвращает [`True`](https://python-all.ru/3.8/library/constants.html#True), если *X* является подстрокой *Y*. Если *X* – пустая строка, результат всегда [`True`](https://python-all.ru/3.8/library/constants.html#True).732733  ```python734  >>> 'ab' in 'abcd'735  True736  >>> 'ad' in 'abcd'737  False738  >>> '' in 'abcd'739  True740  ```741742  Обратите внимание: это не сообщает, где начинается подстрока; если нужна эта информация, используйте строковый метод `find()`.743- Строковые методы `strip()`, `lstrip()` и `rstrip()` теперь имеют необязательный аргумент для указания удаляемых символов. По умолчанию по-прежнему удаляются все пробельные символы:744745  ```python746  >>> '   abc '.strip()747  'abc'748  >>> '><><abc<><><>'.strip('<>')749  'abc'750  >>> '><><abc<><><>\n'.strip('<>')751  'abc<><><>\n'752  >>> u'\u4000\u4001abc\u4000'.strip(u'\u4000')753  u'\u4001abc'754  >>>755  ```756757  (Предложено Simon Brunning и реализовано Walter Dörwald.)758- Строковые методы `startswith()` и `endswith()` теперь принимают отрицательные числа для параметров *start* и *end*.759- Ещё один новый строковый метод – `zfill()`, изначально функция в модуле [`string`](https://python-all.ru/3.8/library/string.html#module-string). `zfill()` дополняет числовую строку нулями слева до указанной ширины. Обратите внимание, что оператор `%` по-прежнему гибче и мощнее, чем `zfill()`.760761  ```python762  >>> '45'.zfill(4)763  '0045'764  >>> '12345'.zfill(4)765  '12345'766  >>> 'goofy'.zfill(6)767  '0goofy'768  ```769770  (Автор: Walter Dörwald.)771- Добавлен новый тип-объект `basestring`. Как 8-битные строки, так и строки Unicode наследуются от этого типа, поэтому `isinstance(obj, basestring)` вернёт [`True`](https://python-all.ru/3.8/library/constants.html#True) для строк любого вида. Это полностью абстрактный тип, поэтому нельзя создавать экземпляры `basestring`.772- Интернированные строки больше не бессмертны и теперь собираются сборщиком мусора обычным образом, когда единственная ссылка на них – из внутреннего словаря интернированных строк. (Реализовано Oren Tirosh.)773774### Оптимизации775776- Создание экземпляров классов нового стиля стало намного быстрее; теперь они быстрее, чем экземпляры классических классов!777- Метод `sort()` списков был существенно переписан Тимом Питерсом, и реализация стала значительно быстрее.778- Умножение больших целых чисел теперь выполняется гораздо быстрее благодаря реализации умножения Карацубы – алгоритма, масштабируемость которого лучше, чем O(n\*n), необходимого для алгоритма умножения из начальной школы. (Оригинальный патч от Кристофера А. Крейга, значительно переработан Тимом Питерсом.)779- Операнд `SET_LINENO` теперь удалён. Это может дать небольшое увеличение скорости в зависимости от особенностей компилятора. Подробнее см. раздел [Другие изменения и исправления](https://python-all.ru/3.8/whatsnew/2.3.html#section-other). (Удалено Michael Hudson.)780- Объекты `xrange()` теперь имеют собственный итератор, что делает `for i in xrange(n)` немного быстрее, чем `for i in range(n)`. (Патч от Raymond Hettinger.)781- Был выполнен ряд небольших перестановок в различных горячих точках для повышения производительности, например, встраивание функции или удаление некоторого кода. (В основном реализовано GvR, но многие люди внесли отдельные изменения.)782783Итоговый результат оптимизаций в версии 2.3: Python 2.3 выполняет тест pystone примерно на 25% быстрее, чем Python 2.2.784785## Новые, улучшенные и устаревшие модули786787Как обычно, стандартная библиотека Python получила ряд улучшений и исправлений ошибок. Вот частичный список наиболее заметных изменений, отсортированный по модулям в алфавитном порядке. Полный список изменений можно найти в файле `Misc/NEWS` в дереве исходного кода или просмотрев журналы CVS.788789- Модуль [`array`](https://python-all.ru/3.8/library/array.html#module-array) теперь поддерживает массивы символов Unicode с использованием символа формата `'u'`. Массивы также теперь поддерживают оператор присваивания `+=` для добавления содержимого другого массива и оператор присваивания `*=` для повторения массива. (Автор: Jason Orendorff.)790- Модуль `bsddb` заменён версией 4.1.6 пакета [PyBSDDB](https://python-all.ru/3.8/whatsnew/2.3.html), предоставляющего более полный интерфейс к транзакционным возможностям библиотеки BerkeleyDB.791792  Старая версия модуля переименована в `bsddb185` и больше не собирается автоматически; для её включения необходимо отредактировать `Modules/Setup`. Обратите внимание, что новый пакет `bsddb` предназначен для совместимости со старым модулем, поэтому обязательно сообщайте об обнаруженных несовместимостях. При обновлении до Python 2.3, если новый интерпретатор скомпилирован с новой версией базовой библиотеки BerkeleyDB, почти наверняка потребуется преобразовать файлы базы данных в новую версию. Это можно сделать довольно легко с помощью новых скриптов `db2pickle.py` и `pickle2db.py`, которые находятся в каталоге `Tools/scripts` дистрибутива. Если вы уже использовали пакет PyBSDDB и импортировали его как `bsddb3`, придётся изменить операторы `import`, чтобы импортировать его как `bsddb`.793- Новый модуль [`bz2`](https://python-all.ru/3.8/library/bz2.html#module-bz2) является интерфейсом к библиотеке сжатия данных bz2. Данные, сжатые bz2, обычно меньше, чем соответствующие данные, сжатые [`zlib`](https://python-all.ru/3.8/library/zlib.html#module-zlib). (Автор: Gustavo Niemeyer.)794- Набор стандартных типов даты/времени добавлен в новый модуль [`datetime`](https://python-all.ru/3.8/library/datetime.html#module-datetime). Подробнее см. в следующем разделе.795- Класс Distutils `Extension` теперь поддерживает дополнительный аргумент конструктора с именем *depends* для перечисления дополнительных исходных файлов, от которых зависит расширение. Это позволяет Distutils перекомпилировать модуль, если какой-либо из зависимых файлов изменён. Например, если `sampmodule.c` включает заголовочный файл `sample.h`, объект `Extension` создаётся следующим образом:796797  ```python798  ext = Extension("samp",799                  sources=["sampmodule.c"],800                  depends=["sample.h"])801  ```802803  Изменение `sample.h` приведёт к перекомпиляции модуля. (Автор: Jeremy Hylton.)804- Прочие мелкие изменения в Distutils: теперь он проверяет переменные окружения `CC`, `CFLAGS`, `CPP`, `LDFLAGS` и `CPPFLAGS`, используя их для переопределения настроек в конфигурации Python (предложено Робертом Вебером).805- Раньше модуль [`doctest`](https://python-all.ru/3.8/library/doctest.html#module-doctest) искал тесты только в докстрингах публичных методов и функций, но теперь проверяет и приватные. Функция `DocTestSuite()` создаёт объект [`unittest.TestSuite`](https://python-all.ru/3.8/library/unittest.html#unittest.TestSuite) из набора тестов [`doctest`](https://python-all.ru/3.8/library/doctest.html#module-doctest).806- Новая функция `gc.get_referents(object)` возвращает список всех объектов, на которые ссылается *object*.807- Модуль [`getopt`](https://python-all.ru/3.8/library/getopt.html#module-getopt) получил новую функцию `gnu_getopt()`, которая поддерживает те же аргументы, что и существующая функция [`getopt()`](https://python-all.ru/3.8/library/getopt.html#module-getopt), но использует режим разбора в стиле GNU. Существующая [`getopt()`](https://python-all.ru/3.8/library/getopt.html#module-getopt) прекращает обработку параметров, как только встречает аргумент, не являющийся параметром, а в режиме GNU обработка продолжается, то есть параметры и аргументы могут смешиваться. Например:808809  ```python810  >>> getopt.getopt(['-f', 'filename', 'output', '-v'], 'f:v')811  ([('-f', 'filename')], ['output', '-v'])812  >>> getopt.gnu_getopt(['-f', 'filename', 'output', '-v'], 'f:v')813  ([('-f', 'filename'), ('-v', '')], ['output'])814  ```815816  (Автор: Peter Åstrand.)817- Модули [`grp`](https://python-all.ru/3.8/library/grp.html#module-grp), [`pwd`](https://python-all.ru/3.8/library/pwd.html#module-pwd) и [`resource`](https://python-all.ru/3.8/library/resource.html#module-resource) теперь возвращают расширенные кортежи:818819  ```python820  >>> import grp821  >>> g = grp.getgrnam('amk')822  >>> g.gr_name, g.gr_gid823  ('amk', 500)824  ```825- Модуль [`gzip`](https://python-all.ru/3.8/library/gzip.html#module-gzip) теперь может обрабатывать файлы размером более 2 ГиБ.826- Новый модуль [`heapq`](https://python-all.ru/3.8/library/heapq.html#module-heapq) содержит реализацию алгоритма очереди с пирамидальным хранением. Пирамида (heap) – это структура данных, подобная массиву, которая хранит элементы в частично отсортированном порядке, так что для каждого индекса *k* выполняются условия `heap[k] <= heap[2*k+1]` и `heap[k] <= heap[2*k+2]`. Это позволяет быстро удалять наименьший элемент, а вставка нового элемента с сохранением свойства пирамиды выполняется за O(lg n). (См. [https://xlinux.nist.gov/dads//HTML/priorityque.html](https://python-all.ru/3.8/whatsnew/2.3.html) для получения дополнительной информации о структуре данных «очередь с приоритетом».)827828  Модуль [`heapq`](https://python-all.ru/3.8/library/heapq.html#module-heapq) предоставляет функции `heappush()` и `heappop()` для добавления и удаления элементов с сохранением свойства пирамиды поверх другой изменяемой последовательности Python. Вот пример с использованием списка Python:829830  ```python831  >>> import heapq832  >>> heap = []833  >>> for item in [3, 7, 5, 11, 1]:834  ...    heapq.heappush(heap, item)835  ...836  >>> heap837  [1, 3, 5, 11, 7]838  >>> heapq.heappop(heap)839  1840  >>> heapq.heappop(heap)841  3842  >>> heap843  [5, 7, 11]844  ```845846  (Автор: Kevin O’Connor.)847- Интегрированная среда разработки IDLE была обновлена с использованием кода из проекта IDLEfork ([http://idlefork.sourceforge.net](https://python-all.ru/3.8/whatsnew/2.3.html)). Наиболее заметная особенность заключается в том, что разрабатываемый код теперь выполняется в подпроцессе, а это означает, что больше нет необходимости в ручных операциях `reload()`. Основной код IDLE был включён в стандартную библиотеку как пакет `idlelib`.848- Модуль [`imaplib`](https://python-all.ru/3.8/library/imaplib.html#module-imaplib) теперь поддерживает IMAP через SSL. (Авторы: Piers Lauder и Tino Lange.)849- Модуль [`itertools`](https://python-all.ru/3.8/library/itertools.html#module-itertools) содержит ряд полезных функций для работы с итераторами, вдохновлённых различными функциями языков ML и Haskell. Например, `itertools.ifilter(predicate, iterator)` возвращает все элементы итератора, для которых функция `predicate()` возвращает [`True`](https://python-all.ru/3.8/library/constants.html#True), а `itertools.repeat(obj, N)` возвращает `obj` *N* раз. В модуле есть и другие функции; подробности см. в справочной документации пакета. (Автор: Raymond Hettinger.)850- Две новые функции в модуле [`math`](https://python-all.ru/3.8/library/math.html#module-math), `degrees(rads)` и `radians(degs)`, выполняют преобразование между радианами и градусами. Другие функции модуля [`math`](https://python-all.ru/3.8/library/math.html#module-math), такие как [`math.sin()`](https://python-all.ru/3.8/library/math.html#math.sin) и [`math.cos()`](https://python-all.ru/3.8/library/math.html#math.cos), всегда требовали входные значения в радианах. Кроме того, в [`math.log()`](https://python-all.ru/3.8/library/math.html#math.log) был добавлен необязательный аргумент *base*, чтобы упростить вычисление логарифмов по основаниям, отличным от `e` и `10`. (Автор: Raymond Hettinger.)851- Несколько новых POSIX-функций (`getpgid()`, `killpg()`, `lchown()`, `loadavg()`, `major()`, `makedev()`, `minor()` и `mknod()`) были добавлены в модуль [`posix`](https://python-all.ru/3.8/library/posix.html#module-posix), лежащий в основе модуля [`os`](https://python-all.ru/3.8/library/os.html#module-os). (Авторы: Gustavo Niemeyer, Geert Jansen и Denis S. Otkidach.)852- В модуле [`os`](https://python-all.ru/3.8/library/os.html#module-os) семейство функций `*stat()` теперь может сообщать доли секунды в метке времени. Такие метки времени представляются в виде чисел с плавающей точкой, аналогично значению, возвращаемому [`time.time()`](https://python-all.ru/3.8/library/time.html#time.time).853854  В ходе тестирования было обнаружено, что некоторые приложения могут сломаться, если метки времени являются числами с плавающей точкой. Для совместимости при использовании кортежного интерфейса модуля `stat_result` метки времени будут представляться целыми числами. При использовании именованных полей (функция, впервые появившаяся в Python 2.2) метки времени по-прежнему представляются целыми числами, если не вызвать `os.stat_float_times()` для включения возврата значений с плавающей точкой:855856  ```python857  >>> os.stat("/tmp").st_mtime858  1034791200859  >>> os.stat_float_times(True)860  >>> os.stat("/tmp").st_mtime861  1034791200.6335014862  ```863864  В Python 2.4 значение по умолчанию изменится – всегда будут возвращаться числа с плавающей точкой.865866  Разработчикам приложений следует включать эту возможность только в том случае, если все их библиотеки корректно работают с метками времени с плавающей точкой, или если они используют API кортежей. При использовании эту возможность следует активировать на уровне приложения, а не пытаться включать её для каждого отдельного вызова.867- Модуль [`optparse`](https://python-all.ru/3.8/library/optparse.html#module-optparse) содержит новый синтаксический анализатор аргументов командной строки, который может преобразовывать значения параметров в определённый тип Python и автоматически генерировать сообщение об использовании. Подробнее см. в следующем разделе.868- Старый и никогда не документировавшийся модуль `linuxaudiodev` объявлен устаревшим, и добавлена новая версия с именем [`ossaudiodev`](https://python-all.ru/3.8/library/ossaudiodev.html#module-ossaudiodev). Модуль был переименован, потому что звуковые драйверы OSS могут использоваться на платформах, отличных от Linux, а интерфейс также был приведён в порядок и обновлён различными способами. (Авторы: Greg Ward и Nicholas FitzRoy-Dale.)869- Новый модуль [`platform`](https://python-all.ru/3.8/library/platform.html#module-platform) содержит ряд функций, которые пытаются определить различные свойства платформы, на которой выполняется программа. Есть функции для получения архитектуры, типа процессора, версии ОС Windows и даже версии дистрибутива Linux. (Автор: Marc-André Lemburg.)870- Объекты синтаксического анализатора, предоставляемые модулем `pyexpat`, теперь могут опционально буферизировать символьные данные, что приводит к меньшему числу вызовов обработчика символьных данных и, следовательно, к более высокой производительности. Установка атрибута `buffer_text` объекта анализатора в значение [`True`](https://python-all.ru/3.8/library/constants.html#True) включает буферизацию.871- Функция `sample(population, k)` была добавлена в модуль [`random`](https://python-all.ru/3.8/library/random.html#module-random). *population* – это последовательность или объект `xrange`, содержащий элементы совокупности, а `sample()` выбирает *k* элементов из совокупности без замены выбранных элементов. *k* может быть любым значением до `len(population)`. Например:872873  ```python874  >>> days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'St', 'Sn']875  >>> random.sample(days, 3)      # Выбрать 3 элемента876  ['St', 'Sn', 'Th']877  >>> random.sample(days, 7)      # Выбрать 7 элементов878  ['Tu', 'Th', 'Mo', 'We', 'St', 'Fr', 'Sn']879  >>> random.sample(days, 7)      # Выбрать 7 снова880  ['We', 'Mo', 'Sn', 'Fr', 'Tu', 'St', 'Th']881  >>> random.sample(days, 8)      # Нельзя выбрать восемь882  Traceback (most recent call last):883    File "<stdin>", line 1, in ?884    File "random.py", line 414, in sample885        raise ValueError, "sample larger than population"886  ValueError: sample larger than population887  >>> random.sample(xrange(1,10000,2), 10)   # Выбрать десять нечётных чисел меньше 10000888  [3407, 3805, 1505, 7023, 2401, 2267, 9733, 3151, 8083, 9195]889  ```890891  Модуль [`random`](https://python-all.ru/3.8/library/random.html#module-random) теперь использует новый алгоритм, вихрь Мерсенна (Mersenne Twister), реализованный на C. Он быстрее и более тщательно изучен, чем предыдущий алгоритм.892893  (Все изменения выполнены Raymond Hettinger.)894- Модуль [`readline`](https://python-all.ru/3.8/library/readline.html#module-readline) также получил несколько новых функций: `get_history_item()`, `get_current_history_length()` и `redisplay()`.895- Модули `rexec` и `Bastion` объявлены мёртвыми, и попытки их импорта будут завершаться с [`RuntimeError`](https://python-all.ru/3.8/library/exceptions.html#RuntimeError). Классы нового стиля предоставляют новые способы выхода из ограниченной среды выполнения, предоставляемой `rexec`, и никто не заинтересован в их исправлении или не имеет на это времени. Если у вас есть приложения, использующие `rexec`, перепишите их для использования чего-то другого.896897  (Использование Python 2.2 или 2.1 не сделает ваши приложения безопаснее, потому что в этих версиях есть известные ошибки в модуле `rexec`. Повторяем: если вы используете `rexec`, немедленно прекратите его использование.)898- Модуль `rotor` объявлен устаревшим, поскольку используемый им алгоритм шифрования не считается безопасным. Если вам нужно шифрование, используйте один из нескольких доступных отдельно модулей AES для Python.899- Модуль [`shutil`](https://python-all.ru/3.8/library/shutil.html#module-shutil) получил функцию `move(src, dest)`, которая рекурсивно перемещает файл или каталог в новое место.900- Поддержка более продвинутой обработки сигналов POSIX была добавлена в модуль [`signal`](https://python-all.ru/3.8/library/signal.html#module-signal), но затем снова удалена, так как оказалось невозможно обеспечить её надёжную работу на разных платформах.901- Модуль [`socket`](https://python-all.ru/3.8/library/socket.html#module-socket) теперь поддерживает тайм-ауты. Вы можете вызвать метод `settimeout(t)` у объекта сокета, чтобы установить тайм-аут в *t* секунд. Последующие операции с сокетом, выполнение которых занимает более *t* секунд, будут прерваны и вызовут исключение [`socket.timeout`](https://python-all.ru/3.8/library/socket.html#socket.timeout).902903  Первоначальная реализация тайм-аута была выполнена Tim O’Malley. Michael Gilfix интегрировал её в модуль Python [`socket`](https://python-all.ru/3.8/library/socket.html#module-socket) и провёл её через длительное рецензирование. После того как код был принят, Guido van Rossum переписал его части. (Это хороший пример совместного процесса разработки в действии.)904- В Windows модуль [`socket`](https://python-all.ru/3.8/library/socket.html#module-socket) теперь поставляется с поддержкой протокола Secure Sockets Layer (SSL).905- Значение макроса C `PYTHON_API_VERSION` теперь доступно на уровне Python как `sys.api_version`. Текущее исключение можно очистить, вызвав новую функцию `sys.exc_clear()`.906- Новый модуль [`tarfile`](https://python-all.ru/3.8/library/tarfile.html#module-tarfile) позволяет читать и записывать архивные файлы формата **tar**. (Автор: Lars Gustäbel.)907- Новый модуль [`textwrap`](https://python-all.ru/3.8/library/textwrap.html#module-textwrap) содержит функции для переноса строк, содержащих абзацы текста. Функция `wrap(text, width)` принимает строку и возвращает список, содержащий текст, разбитый на строки длиной не более заданной ширины. Функция `fill(text, width)` возвращает одну строку, переформатированную так, чтобы поместиться в строки не длиннее выбранной ширины. (Как вы можете догадаться, `fill()` построен поверх `wrap()`. Например:908909  ```python910  >>> import textwrap911  >>> paragraph = "Not a whit, we defy augury: ... more text ..."912  >>> textwrap.wrap(paragraph, 60)913  ["Not a whit, we defy augury: there's a special providence in",914   "the fall of a sparrow. If it be now, 'tis not to come; if it",915   ...]916  >>> print textwrap.fill(paragraph, 35)917  Not a whit, we defy augury: there's918  a special providence in the fall of919  a sparrow. If it be now, 'tis not920  to come; if it be not to come, it921  will be now; if it be not now, yet922  it will come: the readiness is all.923  >>>924  ```925926  Модуль также содержит класс `TextWrapper`, который реализует стратегию переноса текста. Класс `TextWrapper` и функции `wrap()` и `fill()` поддерживают ряд дополнительных именованных аргументов для точной настройки форматирования; за подробностями обращайтесь к документации модуля. (Предоставлено Грегом Уордом.)927- Модули `thread` и [`threading`](https://python-all.ru/3.8/library/threading.html#module-threading) теперь имеют сопутствующие модули `dummy_thread` и [`dummy_threading`](https://python-all.ru/3.8/library/dummy_threading.html#module-dummy_threading), которые предоставляют заглушку (реализацию, ничего не делающую) интерфейса модуля `thread` для платформ, где потоки не поддерживаются. Цель – упростить модули, учитывающие потоки (те, которые *не* полагаются на потоки для выполнения), поместив следующий код в начало:928929  ```python930  try:931      import threading as _threading932  except ImportError:933      import dummy_threading as _threading934  ```935936  В этом примере `_threading` используется как имя модуля, чтобы показать, что используемый модуль не обязательно является настоящим модулем [`threading`](https://python-all.ru/3.8/library/threading.html#module-threading). Код может вызывать функции и использовать классы из `_threading` независимо от поддержки потоков, избегая инструкции [`if`](https://python-all.ru/3.8/reference/compound_stmts.html#if) и делая код немного понятнее. Этот модуль не сможет волшебным образом заставить многопоточный код работать без потоков; код, который ожидает возврата или выполнения чего-либо от другого потока, просто зависнет навсегда.937- Функция `strptime()` модуля [`time`](https://python-all.ru/3.8/library/time.html#module-time) давно была источником раздражения, потому что она использует реализацию `strptime()` из системной библиотеки C, и на разных платформах иногда встречаются странные ошибки. Бретт Кэннон предоставил переносимую реализацию, написанную на чистом Python, которая должна вести себя одинаково на всех платформах.938- Новый модуль [`timeit`](https://python-all.ru/3.8/library/timeit.html#module-timeit) помогает измерить, сколько времени занимает выполнение фрагментов кода Python. Файл `timeit.py` можно запускать прямо из командной строки, или можно импортировать и использовать напрямую класс `Timer` модуля. Вот короткий пример, который выясняет, что быстрее: преобразовать 8-битную строку в Unicode путём добавления к ней пустой строки Unicode или с помощью функции `unicode()`:939940  ```python941  import timeit942943  timer1 = timeit.Timer('unicode("abc")')944  timer2 = timeit.Timer('"abc" + u""')945946  # Провести три испытания947  print timer1.repeat(repeat=3, number=100000)948  print timer2.repeat(repeat=3, number=100000)949950  # На моём ноутбуке это выводит:951  # [0.36831796169281006, 0.37441694736480713, 0.35304892063140869]952  # [0.17574405670166016, 0.18193507194519043, 0.17565798759460449]953  ```954- Модуль `Tix` получил различные исправления ошибок и обновления для текущей версии пакета Tix.955- Модуль `Tkinter` теперь работает с версией Tcl с поддержкой потоков. Модель многопоточности Tcl требует, чтобы виджеты можно было обрабатывать только из того потока, в котором они созданы; обращения из другого потока могут вызвать панику в Tcl. Для некоторых интерфейсов Tcl `Tkinter` теперь автоматически избегает этого, когда виджет обращается из другого потока: он маршализирует команду, передаёт её в правильный поток и ожидает результаты. Другие интерфейсы не могут быть обработаны автоматически, но `Tkinter` теперь будет возбуждать исключение при таком обращении, чтобы вы могли хотя бы узнать о проблеме. См. [https://mail.python.org/pipermail/python-dev/2002-December/031107.html](https://python-all.ru/3.8/whatsnew/2.3.html) для более подробного объяснения этого изменения. (Реализовано Мартином фон Лёвисом.)956- Вызов методов Tcl через `_tkinter` больше не возвращает только строки. Вместо этого, если Tcl возвращает другие объекты, они преобразуются в их эквиваленты на Python, если такие существуют, или оборачиваются объектом `_tkinter.Tcl_Obj`, если эквивалента на Python нет. Это поведение можно контролировать через метод `wantobjects()` объектов `tkapp`.957958  При использовании `_tkinter` через модуль `Tkinter` (как и делают большинство приложений Tkinter), эта возможность всегда включена. Это не должно вызывать проблем совместимости, поскольку Tkinter всегда преобразовывал строковые результаты в типы Python там, где это возможно.959960  Если будут обнаружены какие-либо несовместимости, старое поведение можно восстановить, установив переменную `wantobjects` в модуле `Tkinter` в значение false перед созданием первого объекта `tkapp`.961962  ```python963  import Tkinter964  Tkinter.wantobjects = 0965  ```966967  Любые проблемы, вызванные этим изменением, следует сообщать как об ошибке.968- В модуле `UserDict` появился новый класс `DictMixin`, который определяет все методы словаря для классов, уже имеющих минимальный интерфейс отображения. Это значительно упрощает написание классов, которые должны быть взаимозаменяемы со словарями, например, классов в модуле [`shelve`](https://python-all.ru/3.8/library/shelve.html#module-shelve).969970  Добавление примеси в качестве суперкласса предоставляет полный интерфейс словаря всякий раз, когда класс определяет [`__getitem__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__getitem__), [`__setitem__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__setitem__), [`__delitem__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__delitem__) и `keys()`. Например:971972  ```python973  >>> import UserDict974  >>> class SeqDict(UserDict.DictMixin):975  ...     """Подобие словаря, реализованное с помощью списков."""976  ...     def __init__(self):977  ...         self.keylist = []978  ...         self.valuelist = []979  ...     def __getitem__(self, key):980  ...         try:981  ...             i = self.keylist.index(key)982  ...         except ValueError:983  ...             raise KeyError984  ...         return self.valuelist[i]985  ...     def __setitem__(self, key, value):986  ...         try:987  ...             i = self.keylist.index(key)988  ...             self.valuelist[i] = value989  ...         except ValueError:990  ...             self.keylist.append(key)991  ...             self.valuelist.append(value)992  ...     def __delitem__(self, key):993  ...         try:994  ...             i = self.keylist.index(key)995  ...         except ValueError:996  ...             raise KeyError997  ...         self.keylist.pop(i)998  ...         self.valuelist.pop(i)999  ...     def keys(self):1000  ...         return list(self.keylist)1001  ...1002  >>> s = SeqDict()1003  >>> dir(s)      # Посмотреть, что другие методы словаря реализованы1004  ['__cmp__', '__contains__', '__delitem__', '__doc__', '__getitem__',1005   '__init__', '__iter__', '__len__', '__module__', '__repr__',1006   '__setitem__', 'clear', 'get', 'has_key', 'items', 'iteritems',1007   'iterkeys', 'itervalues', 'keylist', 'keys', 'pop', 'popitem',1008   'setdefault', 'update', 'valuelist', 'values']1009  ```10101011  (Автор: Raymond Hettinger.)1012- Реализация DOM в [`xml.dom.minidom`](https://python-all.ru/3.8/library/xml.dom.minidom.html#module-xml.dom.minidom) теперь может генерировать вывод XML в определенной кодировке, передавая необязательный аргумент encoding методам `toxml()` и `toprettyxml()` узлов DOM.1013- Модуль `xmlrpclib` теперь поддерживает расширение XML-RPC для обработки значений nil, таких как `None` в Python. Значения nil всегда поддерживаются при демаршализации ответа XML-RPC. Чтобы генерировать запросы, содержащие `None`, необходимо передать значение true для параметра *allow\_none* при создании экземпляра `Marshaller`.1014- Новый модуль `DocXMLRPCServer` позволяет создавать самодокументируемые серверы XML-RPC. Запустите его в демонстрационном режиме (как программу), чтобы увидеть его в действии. Если открыть веб-браузером RPC-сервер, появится документация в стиле pydoc; если направить на сервер xmlrpclib, можно вызывать сами методы. (Автор – Брайан Квинлан.)1015- Добавлена поддержка интернационализированных доменных имен (RFC 3454, 3490, 3491, 3492). Кодировка "idna" может использоваться для преобразования между доменным именем в Unicode и его ASCII-совместимой кодировкой (ACE).10161017  ```python1018  >{}>{}> u"www.Alliancefrançaise.nu".encode("idna")1019  'www.xn--alliancefranaise-npb.nu'1020  ```10211022  Модуль [`socket`](https://python-all.ru/3.8/library/socket.html#module-socket) также был расширен для прозрачного преобразования имен хостов в Unicode в версию ACE перед передачей их в библиотеку C. Модули, работающие с именами хостов, такие как `httplib` и [`ftplib`](https://python-all.ru/3.8/library/ftplib.html#module-ftplib)), также поддерживают Unicode-имена хостов; `httplib` также отправляет HTTP-заголовки `Host`, используя ACE-версию доменного имени. [`urllib`](https://python-all.ru/3.8/library/urllib.html#module-urllib) поддерживает URL-адреса Unicode с не-ASCII именами хостов, если часть `path` URL-адреса состоит только из ASCII.10231024  Для реализации этого изменения были добавлены модуль [`stringprep`](https://python-all.ru/3.8/library/stringprep.html#module-stringprep), утилита `mkstringprep` и кодировка `punycode`.10251026### Типы даты/времени10271028Типы даты и времени, подходящие для представления временных меток, были добавлены в виде модуля [`datetime`](https://python-all.ru/3.8/library/datetime.html#module-datetime). Эти типы не поддерживают разные календари или множество причудливых возможностей и придерживаются только основ представления времени.10291030Три основных типа: `date`, представляющий день, месяц и год; [`time`](https://python-all.ru/3.8/library/datetime.html#datetime.time), состоящий из часов, минут и секунд; и [`datetime`](https://python-all.ru/3.8/library/datetime.html#datetime.datetime), который содержит все атрибуты как `date`, так и [`time`](https://python-all.ru/3.8/library/datetime.html#datetime.time). Также существует класс `timedelta`, представляющий разницу между двумя моментами времени, а логика часовых поясов реализуется классами, наследующими от абстрактного класса `tzinfo`.10311032Создавать экземпляры `date` и [`time`](https://python-all.ru/3.8/library/datetime.html#datetime.time) можно либо передавая именованные аргументы соответствующему конструктору, например `datetime.date(year=1972, month=10, day=15)`, либо используя один из нескольких методов класса. Например, метод класса `date.today()` возвращает текущую локальную дату.10331034После создания экземпляры классов даты/времени являются неизменяемыми. Существует ряд методов для создания форматированных строк из объектов:10351036```python1037>>> import datetime1038>>> now = datetime.datetime.now()1039>>> now.isoformat()1040'2002-12-30T21:27:03.994956'1041>>> now.ctime()  # Доступно только для date, datetime1042'Mon Dec 30 21:27:03 2002'1043>>> now.strftime('%Y %d %b')1044'2002 30 Dec'1045```10461047Метод `replace()` позволяет изменить одно или несколько полей экземпляра `date` или [`datetime`](https://python-all.ru/3.8/library/datetime.html#datetime.datetime), возвращая новый экземпляр:10481049```python1050>>> d = datetime.datetime.now()1051>>> d1052datetime.datetime(2002, 12, 30, 22, 15, 38, 827738)1053>>> d.replace(year=2001, hour = 12)1054datetime.datetime(2001, 12, 30, 12, 15, 38, 827738)1055>>>1056```10571058Экземпляры можно сравнивать, хешировать и преобразовывать в строки (результат тот же, что и у `isoformat()`). Экземпляры `date` и [`datetime`](https://python-all.ru/3.8/library/datetime.html#datetime.datetime) можно вычитать друг из друга и прибавлять к экземплярам `timedelta`. Самая большая недостающая возможность – отсутствие в стандартной библиотеке поддержки разбора строк и получения обратно `date` или [`datetime`](https://python-all.ru/3.8/library/datetime.html#datetime.datetime).10591060За дополнительной информацией обращайтесь к справочной документации модуля. (Предоставлено Тимом Питерсом.)10611062### Модуль optparse10631064Модуль [`getopt`](https://python-all.ru/3.8/library/getopt.html#module-getopt) предоставляет простой разбор аргументов командной строки. Новый модуль [`optparse`](https://python-all.ru/3.8/library/optparse.html#module-optparse) (первоначально названный Optik) предоставляет более сложный разбор командной строки, следующий соглашениям Unix, автоматически создаёт вывод для `--help` и может выполнять различные действия для разных опций.10651066Начните с создания экземпляра `OptionParser` и указания ему, какие опции есть у вашей программы.10671068```python1069import sys1070from optparse import OptionParser10711072op = OptionParser()1073op.add_option('-i', '--input',1074              action='store', type='string', dest='input',1075              help='set input filename')1076op.add_option('-l', '--length',1077              action='store', type='int', dest='length',1078              help='set maximum length of output')1079```10801081Разбор командной строки затем выполняется вызовом метода `parse_args()`.10821083```python1084options, args = op.parse_args(sys.argv[1:])1085print options1086print args1087```10881089Метод возвращает объект, содержащий все значения параметров и список строк с остальными аргументами.10901091Теперь запуск скрипта с различными аргументами работает так, как и ожидается. Обратите внимание, что аргумент length автоматически преобразуется в целое число.10921093```console1094$ ./python opt.py -i data arg11095<Values at 0x400cad4c: {'input': 'data', 'length': None}>1096['arg1']1097$ ./python opt.py --input=data --length=41098<Values at 0x400cad2c: {'input': 'data', 'length': 4}>1099[]1100$1101```11021103Справочное сообщение создаётся автоматически:11041105```console1106$ ./python opt.py --help1107usage: opt.py [options]11081109options:1110  -h, --help            show this help message and exit1111  -iINPUT, --input=INPUT1112                        set input filename1113  -lLENGTH, --length=LENGTH1114                        set maximum length of output1115$1116```11171118Подробнее см. документацию модуля.11191120Optik был написан Грегом Уордом (Greg Ward) с учётом предложений участников Getopt SIG.11211122## Pymalloc: специализированный распределитель объектов11231124Pymalloc – специализированный распределитель объектов, написанный Владимиром Марангозовым (Vladimir Marangozov). Он появился в Python 2.1. Pymalloc работает быстрее системного `malloc()` и потребляет меньше памяти при типичных для программ Python сценариях выделения. Распределитель использует функцию C `malloc()` для получения больших пулов памяти, из которых затем выделяет小块 под более мелкие запросы.11251126В версиях 2.1 и 2.2 pymalloc был экспериментальной функцией и не включался по умолчанию; его нужно было явно активировать при компиляции Python, передав параметр `--with-pymalloc` скрипту **configure**. В версии 2.3 pymalloc был доработан и теперь включён по умолчанию; чтобы отключить его, нужно передать `--without-pymalloc`.11271128Для кода на Python это изменение незаметно, однако pymalloc может выявить ошибки в C-расширениях. Авторам модулей-расширений на C следует тестировать свой код с включённым pymalloc, поскольку некорректный код может приводить к аварийному завершению программы.11291130Есть одна особенно распространённая ошибка, вызывающая проблемы. Ранее некоторые функции выделения памяти в C API Python были просто псевдонимами для `malloc()` и `free()` из библиотеки C, поэтому случайный вызов несоответствующих функций не приводил к заметным проблемам. Когда распределитель объектов включён, эти функции больше не являются псевдонимами `malloc()` и `free()`, и ошибочный вызов функции освобождения памяти может вызвать аварийный дамп. Например, если память была выделена через [`PyObject_Malloc()`](https://python-all.ru/3.8/c-api/memory.html#c.PyObject_Malloc), освобождать её нужно через [`PyObject_Free()`](https://python-all.ru/3.8/c-api/memory.html#c.PyObject_Free), а не через `free()`. Некоторые модули, входящие в состав Python, столкнулись с этой проблемой и были исправлены; несомненно, есть и другие сторонние модули, в которых та же ошибка.11311132В рамках этого изменения запутанные множественные интерфейсы для выделения памяти были объединены в два семейства API. Память, выделенная функциями одного семейства, не должна обрабатываться функциями другого. Одно семейство предназначено для выделения блоков памяти, другое – специально для выделения объектов Python.11331134- Для выделения и освобождения произвольного блока памяти используйте семейство «сырая память»: [`PyMem_Malloc()`](https://python-all.ru/3.8/c-api/memory.html#c.PyMem_Malloc), [`PyMem_Realloc()`](https://python-all.ru/3.8/c-api/memory.html#c.PyMem_Realloc) и [`PyMem_Free()`](https://python-all.ru/3.8/c-api/memory.html#c.PyMem_Free).1135- Семейство «память объектов» – это интерфейс к описанному выше механизму pymalloc, оптимизированный для большого количества «мелких» выделений: [`PyObject_Malloc()`](https://python-all.ru/3.8/c-api/memory.html#c.PyObject_Malloc), [`PyObject_Realloc()`](https://python-all.ru/3.8/c-api/memory.html#c.PyObject_Realloc) и [`PyObject_Free()`](https://python-all.ru/3.8/c-api/memory.html#c.PyObject_Free).1136- Для выделения и освобождения объектов Python используйте семейство «объекты»: [`PyObject_New()`](https://python-all.ru/3.8/c-api/allocation.html#c.PyObject_New), [`PyObject_NewVar()`](https://python-all.ru/3.8/c-api/allocation.html#c.PyObject_NewVar) и [`PyObject_Del()`](https://python-all.ru/3.8/c-api/allocation.html#c.PyObject_Del).11371138Благодаря большой работе Тима Питерса (Tim Peters) pymalloc в версии 2.3 также предоставляет отладочные возможности для выявления перезаписи памяти и двойного освобождения как в модулях-расширениях, так и в самом интерпретаторе. Чтобы включить эту поддержку, соберите отладочную версию интерпретатора Python, запустив **configure** с `--with-pydebug`.11391140В помощь разработчикам расширений в исходные тексты Python 2.3 включён заголовочный файл `Misc/pymemcompat.h`, позволяющий расширениям Python использовать интерфейсы выделения памяти версии 2.3 при компиляции с любой версией Python начиная с 1.5.2. Вы можете скопировать этот файл из дистрибутива исходных текстов Python и включить его в исходный код своего расширения.11411142> **См. также**1143>1144> **[https://hg.python.org/cpython/file/default/Objects/obmalloc.c](https://python-all.ru/src/main/Objects/obmalloc.c)**1145>1146> Полные подробности реализации pymalloc можно найти в комментариях в начале файла `Objects/obmalloc.c` в исходных текстах Python. Приведённая выше ссылка указывает на этот файл в SVN-обозревателе python.org.11471148## Изменения в сборке и C API11491150Изменения процесса сборки Python и C API включают:11511152- Реализация обнаружения циклов, используемая сборщиком мусора, доказала свою стабильность, поэтому теперь она обязательна. Сборка Python без неё больше невозможна, а флаг `--with-cycle-gc` у скрипта **configure** был удалён.1153- Python теперь может быть собран как динамическая библиотека (`libpython2.3.so`) – для этого при запуске скрипта **configure** нужно указать `--enable-shared`. (Автор: Ondrej Palkovsky.)1154- Макросы `DL_EXPORT` и `DL_IMPORT` теперь устарели. Функции инициализации модулей-расширений Python теперь следует объявлять с помощью нового макроса `PyMODINIT_FUNC`, а ядро Python будет в основном использовать макросы `PyAPI_FUNC` и `PyAPI_DATA`.1155- Интерпретатор можно скомпилировать без строк документации для встроенных функций и модулей, передав `--without-doc-strings` скрипту **configure**. Это уменьшает исполняемый файл Python примерно на 10%, но при этом будет невозможно получить справку по встроенным объектам Python. (Автор: Gustavo Niemeyer.)1156- The `PyArg_NoArgs()` macro is now deprecated, and code that uses it should be changed. For Python 2.2 and later, the method definition table can specify the [`METH_NOARGS`](https://python-all.ru/3.8/c-api/structures.html#METH_NOARGS) flag, signalling that there are no arguments, and the argument checking can then be removed. If compatibility with pre-2.2 versions of Python is important, the code could use `PyArg_ParseTuple(args, "")` instead, but this will be slower than using [`METH_NOARGS`](https://python-all.ru/3.8/c-api/structures.html#METH_NOARGS).1157- [`PyArg_ParseTuple()`](https://python-all.ru/3.8/c-api/arg.html#c.PyArg_ParseTuple) принимает новые символы формата для беззнаковых целых различных размеров: `B` для `unsigned char`, `H` для `unsigned short int`, `I` для `unsigned int` и `K` для `unsigned long long`.1158- Добавлена новая функция `PyObject_DelItemString(mapping, char *key)` как сокращение для `PyObject_DelItem(mapping, PyString_New(key))`.1159- Файловые объекты теперь управляют своим внутренним строковым буфером по-другому, увеличивая его экспоненциально по мере необходимости. Это привело к значительному ускорению тестов производительности в `Lib/test/test_bufio.py` (по некоторым измерениям, с 57 секунд до 1,7 секунды).1160- Теперь можно определить методы класса и статические методы для типа расширения C, установив флаги [`METH_CLASS`](https://python-all.ru/3.8/c-api/structures.html#METH_CLASS) или [`METH_STATIC`](https://python-all.ru/3.8/c-api/structures.html#METH_STATIC) в структуре [`PyMethodDef`](https://python-all.ru/3.8/c-api/structures.html#c.PyMethodDef) метода.1161- Python теперь включает копию исходного кода Expat XML-парсера, устраняя зависимость от системной версии или локальной установки Expat.1162- Если вы динамически создаёте объекты типов в своём расширении, учтите изменение правил, касающихся атрибутов `__module__` и [`__name__`](https://python-all.ru/3.8/library/stdtypes.html#definition.__name__). Кратко: нужно убедиться, что словарь типа содержит ключ `'__module__'`; указание имени модуля как части имени типа до последней точки больше не будет давать желаемого эффекта. Подробнее читайте в документации по API-ссылкам или в исходном коде.11631164### Изменения, специфичные для платформ11651166Поддержка порта под IBM OS/2 с использованием среды выполнения EMX была объединена с основным деревом исходных текстов Python. EMX – это уровень эмуляции POSIX поверх системных API OS/2. Порт Python для EMX старается поддерживать все возможности, похожие на POSIX, предоставляемые средой выполнения EMX, и в основном это удаётся; `fork()` и [`fcntl()`](https://python-all.ru/3.8/library/fcntl.html#module-fcntl) ограничены недостатками базового уровня эмуляции. Стандартный порт OS/2, использующий компилятор Visual Age от IBM, также получил поддержку регистрозависимой семантики импорта в рамках интеграции порта EMX в CVS. (Автор: Andrew MacIntyre.)11671168В MacOS большинство модулей toolbox были слабо связаны для улучшения обратной совместимости. Это означает, что модули больше не будут загружаться с ошибкой, если в текущей версии ОС отсутствует отдельная процедура. Вместо этого вызов отсутствующей процедуры вызовет исключение. (Автор: Jack Jansen.)11691170Файлы спецификаций RPM, находящиеся в каталоге `Misc/RPM/` дистрибутива исходных текстов Python, были обновлены для версии 2.3. (Автор: Sean Reifschneider.)11711172Другие новые платформы, теперь поддерживаемые Python, включают AtheOS ([http://www.atheos.cx/](https://python-all.ru/3.8/whatsnew/2.3.html)), GNU/Hurd и OpenVMS.11731174## Другие изменения и исправления11751176Как обычно, по всему дереву исходных кодов было разбросано множество других улучшений и исправлений ошибок. Поиск по журналам изменений CVS показывает, что между Python 2.2 и 2.3 было применено 523 патча и исправлено 514 ошибок. Оба числа, вероятно, занижены.11771178Некоторые из наиболее заметных изменений:11791180- Если установлена переменная окружения [`PYTHONINSPECT`](https://python-all.ru/3.8/using/cmdline.html#envvar-PYTHONINSPECT), интерпретатор Python перейдёт в интерактивный режим после выполнения программы Python, как если бы Python был вызван с опцией [`-i`](https://python-all.ru/3.8/using/cmdline.html#cmdoption-i). Переменную окружения можно установить до запуска интерпретатора Python, или она может быть установлена программой Python во время выполнения.1181- Скрипт `regrtest.py` теперь предоставляет способ разрешить «все ресурсы, кроме *foo*». Имя ресурса, переданное опции `-u`, теперь может начинаться с дефиса (`'-'`), что означает «удалить этот ресурс». Например, опция '`-uall,-bsddb`' может использоваться для включения всех ресурсов, кроме `bsddb`.1182- Инструменты, используемые для сборки документации, теперь работают в Cygwin, а также в Unix.1183- Опкод `SET_LINENO` удалён. В незапамятные времена этот опкод был нужен для генерации номеров строк в трассировках и поддержки функций трассировки (например, [`pdb`](https://python-all.ru/3.8/library/pdb.html#module-pdb)). Начиная с Python 1.5 номера строк в трассировках вычисляются с помощью другого механизма, который работает с «python -O». Для Python 2.3 Майкл Хадсон реализовал аналогичную схему для определения момента вызова функции трассировки, полностью устранив необходимость в `SET_LINENO`.11841185  Трудно было бы заметить какие-либо различия в коде Python, кроме небольшого ускорения при запуске Python без [`-O`](https://python-all.ru/3.8/using/cmdline.html#cmdoption-o).11861187  Расширения C, которые обращаются к полю `f_lineno` объектов фрейма, должны вместо этого вызывать `PyCode_Addr2Line(f->f_code, f->f_lasti)`. Это также приведёт к тому, что код будет работать как надо при запуске с «python -O» в более ранних версиях Python.11881189  Интересная новая возможность: функции трассировки теперь могут присваивать значение атрибуту `f_lineno` объектов фрейма, изменяя следующую выполняемую строку. В отладчик [`pdb`](https://python-all.ru/3.8/library/pdb.html#module-pdb) добавлена команда `jump`, использующая эту новую возможность. (Реализовано Richie Hindle.)11901191## Перенос на Python 2.311921193В этом разделе перечислены описанные ранее изменения, которые могут потребовать изменения кода:11941195- [`yield`](https://python-all.ru/3.8/reference/simple_stmts.html#yield) теперь всегда ключевое слово; если оно используется в коде как имя переменной, необходимо выбрать другое имя.1196- Для строк *X* и *Y*, `X in Y` теперь работает, если *X* длиннее одного символа.1197- Конструктор типа [`int()`](https://python-all.ru/3.8/library/functions.html#int) теперь будет возвращать длинное целое число (long) вместо возбуждения исключения [`OverflowError`](https://python-all.ru/3.8/library/exceptions.html#OverflowError), когда строка или число с плавающей точкой слишком велики для целого числа.1198- Если у вас есть строки Unicode, содержащие 8-битные символы, вы должны объявить кодировку файла (UTF-8, Latin-1 или любую другую), добавив комментарий в начало файла. См. раздел [PEP 263: Кодировки исходного кода](https://python-all.ru/3.8/whatsnew/2.3.html#section-encodings) для получения дополнительной информации.1199- Вызов методов Tcl через `_tkinter` больше не возвращает только строки. Вместо этого, если Tcl возвращает другие объекты, эти объекты преобразуются в их эквивалент Python, если таковой существует, или оборачиваются объектом `_tkinter.Tcl_Obj`, если эквивалента Python не существует.1200- Большие восьмеричные и шестнадцатеричные литералы, такие как `0xffffffff`, теперь вызывают [`FutureWarning`](https://python-all.ru/3.8/library/exceptions.html#FutureWarning). В настоящее время они хранятся как 32-битные числа и дают отрицательное значение, но в Python 2.4 они станут положительными длинными целыми числами.12011202  Есть несколько способов исправить это предупреждение. Если вам действительно нужно положительное число, просто добавьте `L` в конец литерала. Если вы пытаетесь получить 32-битное целое число с установленными младшими битами и ранее использовали выражение типа `~(1 << 31)`, вероятно, проще всего начать со всеми установленными битами и очистить нужные старшие биты. Например, чтобы очистить только старший бит (бит 31), можно написать `0xffffffffL &~(1L<<31)`.1203- Больше нельзя отключить assertions, присваивая значение `__debug__`.1204- Функция Distutils `setup()` получила различные новые именованные аргументы, такие как *depends*. Старые версии Distutils будут аварийно завершаться при передаче неизвестных ключевых слов. Решение – проверить наличие новой функции `get_distutil_options()` в вашем `setup.py` и использовать новые ключевые слова только с версией Distutils, которая их поддерживает:12051206  ```python1207  from distutils import core12081209  kw = {'sources': 'foo.c', ...}1210  if hasattr(core, 'get_distutil_options'):1211      kw['depends'] = ['foo.h']1212  ext = Extension(**kw)1213  ```1214- Использование `None` в качестве имени переменной теперь приведёт к предупреждению [`SyntaxWarning`](https://python-all.ru/3.8/library/exceptions.html#SyntaxWarning).1215- Имена типов расширений, определённых модулями, входящими в состав Python, теперь содержат модуль и `'.'` перед именем типа.12161217## Благодарности12181219Автор хотел бы поблагодарить следующих людей за предложения, исправления и помощь с различными черновиками этой статьи: 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.1220