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

2.4.md

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

1> **Источник:** https://python-all.ru/3.1/whatsnew/2.4.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Что нового в Python 2.489| Автор: | A.M. Kuchling |10| --- | --- |1112В этой статье описываются новые возможности Python 2.4.1, выпущенного 30 марта, 2005.1314Python 2.4 – релиз среднего размера. Он не вносит столько изменений, как радикальный Python 2.2, но добавляет больше возможностей, чем консервативный 2.3 релиз. Наиболее значительные новые языковые возможности – это декораторы функций и выражения-генераторы; большинство остальных изменений касаются стандартной библиотеки.1516Согласно журналам изменений CVS, между Python 2.3 и 2.4 было применено 481 исправление и исправлено 502 ошибки. Обе цифры, скорее всего, занижены.1718Эта статья не ставит целью дать полную спецификацию каждой новой возможности, а вместо этого предоставляет краткое введение в каждую из них. За полными подробностями следует обращаться к документации Python 2.4, например, к справочнику по библиотеке Python и руководству по языку Python. Часто вас будут отсылать к PEP для конкретной новой возможности, где объясняются детали реализации и обоснование проекта.1920## PEP 218: Встроенные объекты множеств2122В Python 2.3 был представлен модуль `sets`. Теперь в ядро Python добавлены реализации типов данных set на C в виде двух новых встроенных типов: `set(iterable)()` и `frozenset(iterable)()`. Они обеспечивают высокую скорость проверки принадлежности, удаления дубликатов из последовательностей и математических операций, таких как объединение, пересечение, разность и симметрическая разность.2324```python25>>> a = set('abracadabra')              # Сформировать множество из строки26>>> 'z' in a                            # быстрая проверка принадлежности27False28>>> a                                   # уникальные буквы в a29set(['a', 'r', 'b', 'c', 'd'])30>>> ''.join(a)                          # Преобразовать обратно в строку31'arbcd'3233>>> b = set('alacazam')                 # Сформировать второе множество34>>> a - b                               # буквы, которые есть в a, но нет в b35set(['r', 'd', 'b'])36>>> a | b                               # Буквы из a или b37set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])38>>> a & b                               # буквы, которые есть и в a, и в b39set(['a', 'c'])40>>> a ^ b                               # буквы, которые есть в a или в b, но не в обоих41set(['r', 'd', 'b', 'm', 'z', 'l'])4243>>> a.add('z')                          # Добавить новый элемент44>>> a.update('wxy')                     # Добавить несколько новых элементов45>>> a46set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])47>>> a.remove('x')                       # извлечь один элемент48>>> a49set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])50```5152Тип [`frozenset()`](https://python-all.ru/3.1/library/stdtypes.html#frozenset) является неизменяемой версией [`set()`](https://python-all.ru/3.1/library/stdtypes.html#set). Поскольку он неизменяем и хешируем, его можно использовать в качестве ключа словаря или как элемент другого множества.5354Модуль `sets` остаётся в стандартной библиотеке и может быть полезен, если вы хотите создать подкласс классов `Set` или `ImmutableSet`. В настоящее время нет планов объявлять модуль устаревшим.5556> **См. также**57>58> **[**PEP 218**](https://python-all.ru/3.1/whatsnew/2.4.html) – Добавление встроенного типа объектов-множеств**59>60> Изначально предложено Грегом Уилсоном, окончательно реализовано Рэймондом Хеттингером.6162## PEP 237: Унификация длинных целых и целых чисел6364Длительный процесс перехода по этому PEP, начатый в Python 2.2, делает очередной шаг вперёд в Python 2.4. В версии 2.3 некоторые целочисленные операции, которые вели бы себя иначе после унификации int/long, вызывали предупреждения [`FutureWarning`](https://python-all.ru/3.1/library/exceptions.html#FutureWarning) и возвращали значения, ограниченные 32 или 64 битами (в зависимости от вашей платформы). В версии 2.4 эти выражения больше не генерируют предупреждение, а вместо этого возвращают другой результат, который обычно является длинным целым.6566Проблемные выражения – это в основном сдвиги влево и длинные шестнадцатеричные и восьмеричные константы. Например, `2 << 32` в 2.3 вызывает предупреждение, вычисляясь в 0 на 32-битных платформах. В Python 2.4 это выражение теперь возвращает правильный ответ: 8589934592.6768> **См. также**69>70> **[**PEP 237**](https://python-all.ru/3.1/whatsnew/2.4.html) – Унификация длинных целых и целых чисел**71>72> Оригинальный PEP написан Моше Задкой и GvR. Изменения для 2.4 были реализованы Калле Свенссоном.7374## PEP 289: Выражения-генераторы7576Возможность итераторов, введённая в Python 2.2, и модуль [`itertools`](https://python-all.ru/3.1/library/itertools.html#module-itertools) упрощают написание программ, которые проходят по большим наборам данных без необходимости держать весь набор данных в памяти одновременно. Списковые включения не очень вписываются в эту картину, потому что они создают объект списка Python, содержащий все элементы. Это неизбежно загружает все объекты в память, что может быть проблемой, если ваш набор данных очень велик. При попытке написать программу в функциональном стиле было бы естественно написать что-то вроде:7778```python79links = [link for link in get_all_links() if not link.followed]80for link in links:81    ...82```8384вместо8586```python87for link in get_all_links():88    if link.followed:89        continue90    ...91```9293Первая форма более лаконична и, возможно, более читаема, но если вы работаете с большим количеством объектов ссылок, вам придётся писать вторую форму, чтобы избежать одновременного хранения всех объектов ссылок в памяти.9495Выражения-генераторы работают аналогично списковым включениям, но не материализуют весь список; вместо этого они создают генератор, который будет возвращать элементы один за другим. Приведённый выше пример можно записать так:9697```python98links = (link for link in get_all_links() if not link.followed)99for link in links:100    ...101```102103Выражения-генераторы всегда должны быть заключены в круглые скобки, как в приведённом выше примере. Скобки, обозначающие вызов функции, тоже подходят, поэтому если вы хотите создать итератор, который будет немедленно передан функции, вы можете написать:104105```python106print sum(obj.count for obj in list_all_objects())107```108109Выражения-генераторы отличаются от списковых включений в различных мелочах. Наиболее заметно, что переменная цикла (*obj* в примере выше) недоступна за пределами выражения-генератора. Списковые включения оставляют переменную присвоенной её последнему значению; будущие версии Python изменят это, сделав списковые включения соответствующими выражениям-генераторам в этом отношении.110111> **См. также**112>113> **[**PEP 289**](https://python-all.ru/3.1/whatsnew/2.4.html) – Выражения-генераторы**114>115> Предложено Рэймондом Хеттингером, реализовано Дживоном Сео при ранних усилиях, направляемых Хе-Шиком Чаном.116117## PEP 292: Более простые подстановки в строках118119Некоторые новые классы в стандартной библиотеке предоставляют альтернативный механизм для подстановки переменных в строки; этот стиль подстановки может быть лучше для приложений, где неподготовленным пользователям нужно редактировать шаблоны.120121Обычный способ подстановки переменных по имени – оператор `%`:122123```python124>>> '%(page)i: %(title)s' % {'page':2, 'title': 'The Best of Times'}125'2: The Best of Times'126```127128При написании строки шаблона легко забыть `i` или `s` после закрывающей скобки. Это не большая проблема, если шаблон находится в модуле Python, потому что вы запускаете код, получаете «Unsupported format character» [`ValueError`](https://python-all.ru/3.1/library/exceptions.html#ValueError) и исправляете проблему. Однако рассмотрим такое приложение, как Mailman, где строки шаблонов или переводы редактируются пользователями, которые не знакомы с языком Python. Синтаксис форматной строки сложно объяснить таким пользователям, и если они допускают ошибку, трудно предоставить им полезную обратную связь.129130PEP 292 добавляет класс `Template` в модуль [`string`](https://python-all.ru/3.1/library/string.html#module-string), который использует `$` для обозначения подстановки:131132```python133>>> import string134>>> t = string.Template('$page: $title')135>>> t.substitute({'page':2, 'title': 'The Best of Times'})136'2: The Best of Times'137```138139Если ключ отсутствует в словаре, метод `substitute()` вызовет исключение [`KeyError`](https://python-all.ru/3.1/library/exceptions.html#KeyError). Существует также метод `safe_substitute()`, который игнорирует отсутствующие ключи:140141```python142>>> t = string.Template('$page: $title')143>>> t.safe_substitute({'page':3})144'3: $title'145```146147> **См. также**148>149> **[**PEP 292**](https://python-all.ru/3.1/whatsnew/2.4.html) – Упрощённые строковые подстановки**150>151> Написано и реализовано Barry Warsaw.152153## PEP 318: Декораторы функций и методов154155Python 2.2 расширил объектную модель Python, добавив статические методы и методы класса, но не расширил синтаксис Python для предоставления нового способа определения статических методов или методов класса. Вместо этого нужно было написать инструкцию [`def`](https://python-all.ru/3.1/reference/compound_stmts.html#def) обычным образом и передать полученный метод функции [`staticmethod()`](https://python-all.ru/3.1/library/functions.html#staticmethod) или [`classmethod()`](https://python-all.ru/3.1/library/functions.html#classmethod), которая обернула бы функцию как метод нового типа. Ваш код выглядел бы так:156157```python158class C:159   def meth (cls):160       ...161162   meth = classmethod(meth)   # перепривязать имя к обёрнутому методу класса163```164165Если метод был очень длинным, было легко пропустить или забыть вызов [`classmethod()`](https://python-all.ru/3.1/library/functions.html#classmethod) после тела функции.166167Всегда предполагалось добавить синтаксис, чтобы сделать такие определения более читаемыми, но на момент выхода 2.2 хороший синтаксис не был очевиден. Сегодня хороший синтаксис *всё ещё* не очевиден, но пользователи просят более простого доступа к этой возможности; был добавлен новый синтаксический элемент для удовлетворения этой потребности.168169Новая возможность называется «декораторы функций». Название происходит от идеи, что [`classmethod()`](https://python-all.ru/3.1/library/functions.html#classmethod), [`staticmethod()`](https://python-all.ru/3.1/library/functions.html#staticmethod) и подобные им хранят дополнительную информацию в объекте функции; они *украшают* функции дополнительными деталями.170171Обозначение заимствовано из Java и использует символ `'@'` как индикатор. С использованием нового синтаксиса приведённый выше пример был бы записан так:172173```python174class C:175176   @classmethod177   def meth (cls):178       ...179```180181Запись `@classmethod` является сокращением для присваивания `meth=classmethod(meth)`. В более общем случае, если у вас есть следующее:182183```python184@A185@B186@C187def f ():188    ...189```190191Это эквивалентно следующему коду без декораторов:192193```python194def f(): ...195f = A(B(C(f)))196```197198Декораторы должны располагаться на строке перед определением функции, по одному декоратору на строку, и не могут находиться на той же строке, что и инструкция def, то есть запись `@A def f(): ...` недопустима. Декорировать можно только определения функций, либо на уровне модуля, либо внутри класса; определения классов декорировать нельзя.199200Декоратор – это просто функция, которая принимает декорируемую функцию в качестве аргумента и возвращает либо ту же функцию, либо какой-то новый объект. Возвращаемое значение декоратора не обязано быть вызываемым (хотя обычно оно вызываемое), если только к результату не будут применяться другие декораторы. Написать собственные декораторы легко. Следующий простой пример просто устанавливает атрибут у объекта функции:201202```python203>>> def deco(func):204...    func.attr = 'decorated'205...    return func206...207>>> @deco208... def f(): pass209...210>>> f211<function f at 0x402ef0d4>212>>> f.attr213'decorated'214>>>215```216217В качестве чуть более реалистичного примера следующий декоратор проверяет, что переданный аргумент является целым числом:218219```python220def require_int (func):221    def wrapper (arg):222        assert isinstance(arg, int)223        return func(arg)224225    return wrapper226227@require_int228def p1 (arg):229    print arg230231@require_int232def p2(arg):233    print arg*2234```235236Пример в [**PEP 318**](https://python-all.ru/3.1/whatsnew/2.4.html) содержит более продвинутую версию этой идеи, которая позволяет как указать требуемый тип, так и проверить возвращаемый тип.237238Функции-декораторы могут принимать аргументы. Если аргументы переданы, ваша функция-декоратор вызывается только с этими аргументами и должна вернуть новую функцию-декоратор; эта функция должна принимать одну функцию и возвращать функцию, как описано ранее. Другими словами, `@A @B @C(args)` превращается в:239240```python241def f(): ...242_deco = C(args)243f = A(B(_deco(f)))244```245246Правильно реализовать это может быть немного запутанно, но не слишком сложно.247248Небольшое связанное изменение делает атрибут `func_name` функций доступным для записи. Этот атрибут используется для отображения имён функций в трассировках стека, поэтому декораторы должны изменять имя любой новой функции, которая создаётся и возвращается.249250> **См. также**251>252> **[**PEP 318**](https://python-all.ru/3.1/whatsnew/2.4.html) – Декораторы функций, методов и классов**253>254> Авторы: Kevin D. Smith, Jim Jewett и Skip Montanaro. Несколько человек написали патчи, реализующие декораторы функций, но тот, который был фактически включён, – патч #979728, написанный Mark Russell.255>256> **[http://www.python.org/moin/PythonDecoratorLibrary](https://python-all.ru/3.1/whatsnew/2.4.html)**257>258> Эта вики-страница содержит несколько примеров декораторов.259260## PEP 322: Обратная итерация261262Новая встроенная функция `reversed(seq)()` принимает последовательность и возвращает итератор, перебирающий элементы последовательности в обратном порядке.263264```python265>>> for i in reversed(xrange(1,4)):266...    print i267...268326922701271```272273По сравнению с расширенной срезкой, такой как `range(1,4)[::-1]`, функция [`reversed()`](https://python-all.ru/3.1/library/functions.html#reversed) легче читается, работает быстрее и использует значительно меньше памяти.274275Обратите внимание: [`reversed()`](https://python-all.ru/3.1/library/functions.html#reversed) принимает только последовательности, а не произвольные итераторы. Если вы хотите перевернуть итератор, сначала преобразуйте его в список с помощью [`list()`](https://python-all.ru/3.1/library/functions.html#list).276277```python278>>> input = open('/etc/passwd', 'r')279>>> for line in reversed(list(input)):280...   print line281...282root:*:0:0:System Administrator:/var/root:/bin/tcsh283  ...284```285286> **См. также**287>288> **[**PEP 322**](https://python-all.ru/3.1/whatsnew/2.4.html) – Обратная итерация**289>290> Написано и реализовано Raymond Hettinger.291292## PEP 324: Новый модуль подпроцесс293294Стандартная библиотека предоставляет несколько способов запуска подпроцесса, предлагая разные возможности и разный уровень сложности. `os.system(command)()` прост в использовании, но медлителен (он запускает процесс оболочки, который выполняет команду) и опасен (нужно осторожно экранировать метасимволы оболочки). Модуль `popen2` предлагает классы, которые могут захватывать стандартный вывод и стандартную ошибку подпроцесса, но названия классов сбивают с толку. Модуль [`subprocess`](https://python-all.ru/3.1/library/subprocess.html#module-subprocess) исправляет это, предоставляя единый интерфейс, содержащий все необходимые возможности.295296Вместо набора классов `popen2` модуль [`подпроцесса`](https://python-all.ru/3.1/library/subprocess.html#module-subprocess) содержит один класс с именем `Popen`, конструктор которого поддерживает ряд различных именованных аргументов.297298```python299class Popen(args, bufsize=0, executable=None,300            stdin=None, stdout=None, stderr=None,301            preexec_fn=None, close_fds=False, shell=False,302            cwd=None, env=None, universal_newlines=False,303            startupinfo=None, creationflags=0):304```305306*args* обычно представляет собой последовательность строк, которые будут аргументами программы, выполняемой как подпроцесс. (Если аргумент *shell* равен true, *args* может быть строкой, которая затем будет передана оболочке для интерпретации, так же как это делает [`os.system()`](https://python-all.ru/3.1/library/os.html#os.system).)307308*stdin*, *stdout* и *stderr* определяют, какими будут потоки ввода, вывода и ошибок подпроцесса. Можно передать файловый объект или файловый дескриптор, или использовать константу `subprocess.PIPE` для создания канала между подпроцессом и родительским процессом.309310Конструктор имеет ряд удобных опций:311312- *close\_fds* требует, чтобы все файловые дескрипторы были закрыты перед запуском подпроцесса.313- *cwd* указывает рабочий каталог, в котором будет выполняться подпроцесс (по умолчанию используется рабочий каталог родительского процесса).314- *env* – это словарь, задающий переменные окружения.315- *preexec\_fn* – это функция, которая вызывается перед запуском дочернего процесса.316- *universal\_newlines* открывает ввод и вывод дочернего процесса с помощью универсального перевода строк Python.317318После создания экземпляра `Popen` можно вызвать его метод `wait()`, чтобы приостановить выполнение до завершения подпроцесса, `poll()` – чтобы проверить, завершился ли он без ожидания, или `communicate(data)()`, чтобы отправить строку *data* на стандартный ввод подпроцесса. Затем `communicate(data)()` считывает любые данные, отправленные подпроцессом на стандартный вывод или стандартную ошибку, возвращая кортеж `(stdout_data, stderr_data)`.319320`call()` – это сокращение, которое передаёт свои аргументы конструктору `Popen`, ожидает завершения команды и возвращает код состояния подпроцесса. Он может служить более безопасным аналогом [`os.system()`](https://python-all.ru/3.1/library/os.html#os.system):321322```python323sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])324if sts == 0:325    # Успех326    ...327else:328    # dpkg вернул ошибку329    ...330```331332Команда выполняется без использования оболочки. Если вы действительно хотите использовать оболочку, можно добавить `shell=True` в качестве именованного аргумента и передать строку вместо последовательности:333334```python335sts = subprocess.call('dpkg -i /tmp/new-package.deb', shell=True)336```337338В PEP приведены различные примеры кода на shell и Python и показано, как их можно преобразовать в код Python, использующий модуль [`подпроцесса`](https://python-all.ru/3.1/library/subprocess.html#module-subprocess). Настоятельно рекомендуется прочитать этот раздел PEP.339340> **См. также**341>342> **[**PEP 324**](https://python-all.ru/3.1/whatsnew/2.4.html) - подпроцесс - новый модуль для работы с процессами**343>344> Написан и реализован Питером Острандом (Peter Åstrand) при содействии Фредрика Лунда (Fredrik Lundh) и других.345346## PEP 327: тип данных Decimal347348Python всегда поддерживал числа с плавающей запятой (FP), основанные на типе C `double`, как тип данных. Однако, хотя большинство языков программирования предоставляют тип с плавающей запятой, многие люди (даже программисты) не знают, что числа с плавающей запятой не представляют некоторые десятичные дроби точно. Новый тип `Decimal` может представлять эти дроби точно, с точностью, задаваемой пользователем.349350### Зачем нужен Decimal?351352Ограничения возникают из-за представления, используемого для чисел с плавающей точкой. Числа с плавающей точкой состоят из трёх компонентов:353354- Знак, который может быть положительным или отрицательным.355- Мантисса, которая представляет собой однозначное двоичное число, за которым следует дробная часть. Например, `1.01` в двоичной записи – это `1 + 0/2 + 1/4`, или 1.25 в десятичной записи.356- Экспонента, которая указывает, где находится десятичная точка в представляемом числе.357358Например, число 1.25 имеет положительный знак, мантиссу 1.01 (в двоичной системе) и экспоненту 0 (десятичную точку сдвигать не нужно). Число 5 имеет те же знак и мантиссу, но экспонента равна 2, потому что мантисса умножается на 4 (2 в степени экспоненты 2); 1.25 \* 4 = 5.359360Современные системы обычно поддерживают числа с плавающей точкой, соответствующие стандарту IEEE 754. Тип C `double` обычно реализуется как 64-битное число IEEE 754, в котором 52 бита отведено под мантиссу. Это означает, что числа могут быть заданы только с точностью 52 бита. Если нужно представить числа с бесконечно повторяющимся разложением, разложение обрезается после 52 бит. К сожалению, большинству программного обеспечения требуется вывод в десятичной системе, а обычные десятичные дроби часто являются бесконечными дробями в двоичной системе. Например, десятичное 1.1 в двоичной системе – это `1.0001100110011 ...`; 0.1 = 1/16 + 1/32 + 1/256 плюс бесконечное число дополнительных членов. IEEE 754 вынужден обрезать эту бесконечно повторяющуюся дробь после 52 разрядов, поэтому представление оказывается слегка неточным.361362Иногда эту неточность можно увидеть при выводе числа:363364```python365>>> 1.13661.1000000000000001367```368369Неточность не всегда видна при выводе числа, потому что преобразование числа с плавающей запятой в десятичную строку выполняется библиотекой C, и большинство библиотек C стараются выдавать разумный результат. Однако даже если она не отображается, неточность всё равно присутствует, и последующие операции могут увеличить ошибку.370371Для многих приложений это не имеет значения. Если я строю график точек и отображаю их на мониторе, разница между 1.1 и 1.1000000000000001 слишком мала, чтобы быть заметной. Отчёты часто ограничивают вывод определённым количеством десятичных знаков, и если округлить число до двух, трёх или даже восьми знаков, ошибка никогда не проявляется. Однако для приложений, где это важно, реализация собственных арифметических процедур требует больших усилий.372373Следовательно, был создан тип `Decimal`.374375### Тип `Decimal`376377В стандартную библиотеку Python был добавлен новый модуль [`decimal`](https://python-all.ru/3.1/library/decimal.html#module-decimal). Он содержит два класса: `Decimal` и `Context`. Экземпляры `Decimal` представляют числа, а экземпляры `Context` используются для инкапсуляции различных настроек, таких как точность и режим округления по умолчанию.378379Экземпляры `Decimal` неизменяемы, как обычные целые числа Python и числа с плавающей запятой; после создания нельзя изменить значение, которое представляет экземпляр. Экземпляры `Decimal` можно создавать из целых чисел или строк:380381```python382>>> import decimal383>>> decimal.Decimal(1972)384Decimal("1972")385>>> decimal.Decimal("1.1")386Decimal("1.1")387```388389Также можно передавать кортежи, содержащие знак, мантиссу, представленную в виде кортежа десятичных цифр, и экспоненту:390391```python392>>> decimal.Decimal((1, (1, 4, 7, 5), -2))393Decimal("-14.75")394```395396Предостережение: бит знака – это логическое значение, поэтому 0 означает положительное число, а 1 – отрицательное.397398Преобразование чисел с плавающей запятой создаёт небольшую проблему: должно ли число с плавающей точкой, представляющее 1.1, превращаться в десятичное число для ровно 1.1, или для 1.1 плюс все неточности, которые вносятся? Было решено обойти эту проблему и исключить такое преобразование из API. Вместо этого следует преобразовать число с плавающей запятой в строку с нужной точностью и передать строку конструктору `Decimal`:399400```python401>>> f = 1.1402>>> decimal.Decimal(str(f))403Decimal("1.1")404>>> decimal.Decimal('%.12f' % f)405Decimal("1.100000000000")406```407408Получив экземпляры `Decimal`, можно выполнять над ними обычные математические операции. Есть одно ограничение: для возведения в степень требуется целый показатель степени:409410```python411>>> a = decimal.Decimal('35.72')412>>> b = decimal.Decimal('1.73')413>>> a+b414Decimal("37.45")415>>> a-b416Decimal("33.99")417>>> a*b418Decimal("61.7956")419>>> a/b420Decimal("20.64739884393063583815028902")421>>> a ** 2422Decimal("1275.9184")423>>> a**b424Traceback (most recent call last):425  ...426decimal.InvalidOperation: x ** (non-integer)427```428429Экземпляры `Decimal` можно комбинировать с целыми числами, но не с числами с плавающей запятой:430431```python432>>> a + 4433Decimal("39.72")434>>> a + 4.5435Traceback (most recent call last):436  ...437TypeError: You can interact Decimal only with int, long or Decimal data types.438>>>439```440441Числа `Decimal` можно использовать с модулями [`math`](https://python-all.ru/3.1/library/math.html#module-math) и [`cmath`](https://python-all.ru/3.1/library/cmath.html#module-cmath), но учтите, что перед выполнением операции они будут немедленно преобразованы в числа с плавающей запятой, что может привести к потере точности и правильности. В результате вы также получите обычное число с плавающей запятой, а не `Decimal`.442443```python444>>> import math, cmath445>>> d = decimal.Decimal('123456789012.345')446>>> math.sqrt(d)447351364.18288201344448>>> cmath.sqrt(-d)449351364.18288201344j450```451452Экземпляры `Decimal` имеют метод `sqrt()`, который возвращает `Decimal`, но если нужны другие функции, например тригонометрические, их придётся реализовать самостоятельно.453454```python455>>> d.sqrt()456Decimal("351364.1828820134592177245001")457```458459### Тип `Context`460461Экземпляры класса `Context` инкапсулируют несколько настроек для операций с десятичными числами:462463- `prec` – это точность, количество десятичных знаков.464- `rounding` задаёт режим округления. Модуль [`decimal`](https://python-all.ru/3.1/library/decimal.html#module-decimal) содержит константы для различных вариантов: `ROUND_DOWN`, `ROUND_CEILING`, `ROUND_HALF_EVEN` и другие.465- `traps` – это словарь, определяющий, что происходит при возникновении определённых ошибочных ситуаций: либо возбуждается исключение, либо возвращается значение. Некоторые примеры ошибочных ситуаций: деление на ноль, потеря точности и переполнение.466467Контекст по умолчанию, локальный для потока, доступен при вызове `getcontext()`; можно изменять свойства этого контекста, чтобы менять точность, округление или обработку ловушек. Следующий пример показывает эффект изменения точности контекста по умолчанию:468469```python470>>> decimal.getcontext().prec47128472>>> decimal.Decimal(1) / decimal.Decimal(7)473Decimal("0.1428571428571428571428571429")474>>> decimal.getcontext().prec = 9475>>> decimal.Decimal(1) / decimal.Decimal(7)476Decimal("0.142857143")477```478479Действие по умолчанию для ошибочных ситуаций выбирается; модуль может либо вернуть специальное значение, например, бесконечность или не-число, либо возбудить исключение:480481```python482>>> decimal.Decimal(1) / decimal.Decimal(0)483Traceback (most recent call last):484  ...485decimal.DivisionByZero: x / 0486>>> decimal.getcontext().traps[decimal.DivisionByZero] = False487>>> decimal.Decimal(1) / decimal.Decimal(0)488Decimal("Infinity")489>>>490```491492Экземпляр `Context` также имеет различные методы для форматирования чисел, такие как `to_eng_string()` и `to_sci_string()`.493494Дополнительную информацию можно найти в документации модуля [`decimal`](https://python-all.ru/3.1/library/decimal.html#module-decimal), который включает краткое руководство для начинающих и справочный материал.495496> **См. также**497>498> **[**PEP 327**](https://python-all.ru/3.1/whatsnew/2.4.html) – Десятичный тип данных**499>500> Автор: Facundo Batista, реализовано Facundo Batista, Eric Price, Raymond Hettinger, Aahz и Tim Peters.501>502> **[http://www.lahey.com/float.htm](https://python-all.ru/3.1/whatsnew/2.4.html)**503>504> В статье используется код на Фортране для иллюстрации многих проблем, которые может вызвать неточность вычислений с плавающей запятой.505>506> **[http://www2.hursley.ibm.com/decimal/](https://python-all.ru/3.1/whatsnew/2.4.html)**507>508> Описание представления на основе десятичной системы. Это представление предлагается в качестве стандарта и лежит в основе нового десятичного типа Python. Большая часть этого материала была написана Mike Cowlishaw, разработчиком языка Rexx.509510## PEP 328: Многострочные импорты511512Одно из изменений языка – небольшое синтаксическое улучшение, направленное на упрощение импорта множества имён из модуля. В инструкции `from module import names` параметр *names* представляет собой последовательность имён, разделённых запятыми. Если последовательность очень длинная, можно либо написать несколько инструкций импорта из одного модуля, либо использовать обратную косую черту для переноса строк, например:513514```python515from SimpleXMLRPCServer import SimpleXMLRPCServer,\516            SimpleXMLRPCRequestHandler,\517            CGIXMLRPCRequestHandler,\518            resolve_dotted_attribute519```520521Синтаксическое изменение в Python 2.4 просто позволяет помещать имена в круглые скобки. Python игнорирует переводы строк внутри выражений в скобках, поэтому обратная косая черта больше не нужна:522523```python524from SimpleXMLRPCServer import (SimpleXMLRPCServer,525                                SimpleXMLRPCRequestHandler,526                                CGIXMLRPCRequestHandler,527                                resolve_dotted_attribute)528```529530PEP также предлагает, чтобы все инструкции [`import`](https://python-all.ru/3.1/reference/simple_stmts.html#import) были абсолютными импортами, с ведущим символом `.`, указывающим на относительный импорт. Эта часть PEP не была реализована в Python 2.4, но была завершена в Python 2.5.531532> **См. также**533>534> **[**PEP 328**](https://python-all.ru/3.1/whatsnew/2.4.html) – Импорт: многострочный и абсолютный/относительный**535>536> Автор: Aahz. Многострочные импорты реализованы Dima Dorfman.537538## PEP 331: Преобразования чисел с плавающей запятой/строк, не зависящие от локали539540Модуль [`locale`](https://python-all.ru/3.1/library/locale.html#module-locale) позволяет программам на Python выбирать различные преобразования и соглашения отображения, локализованные для конкретной страны или языка. Однако модуль был осторожен, чтобы не изменять числовую локаль, поскольку различные функции в реализации Python требовали, чтобы числовая локаль оставалась установленной на локаль `'C'`. Часто это происходило из-за того, что код использовал функцию `atof()` из библиотеки C.541542Однако отказ от установки числовой локали вызывал проблемы для расширений, использующих сторонние C-библиотеки, поскольку у них не была установлена правильная локаль. Показательным примером была GTK+, виджеты пользовательского интерфейса которой не отображали числа в текущей локали.543544Решение, описанное в PEP, заключается в добавлении в Python API трёх новых функций, которые выполняют преобразования только в ASCII, игнорируя настройки локали:545546- `PyOS_ascii_strtod(str, ptr)()` и `PyOS_ascii_atof(str, ptr)()` обе преобразуют строку в C `double`.547- `PyOS_ascii_formatd(buffer, buf_len, format, d)()` преобразует `double` в строку ASCII.548549Код этих функций был взят из библиотеки GLib ([http://library.gnome.org/devel/glib/stable/](https://python-all.ru/3.1/whatsnew/2.4.html)), разработчики которой любезно перелицензировали соответствующие функции и передали их Python Software Foundation. Теперь модуль [`locale`](https://python-all.ru/3.1/library/locale.html#module-locale) может изменять числовую локаль, позволяя таким расширениям, как GTK+, давать правильные результаты.550551> **См. также**552>553> **[**PEP 331**](https://python-all.ru/3.1/whatsnew/2.4.html) – Преобразования чисел с плавающей запятой/строк, не зависящие от локали**554>555> Автор – Christian R. Reis, реализация – Gustavo Carneiro.556557## Прочие изменения языка558559Ниже перечислены все изменения, которые Python 2.4 вносит в ядро языка Python.560561- Добавлены декораторы для функций и методов ([**PEP 318**](https://python-all.ru/3.1/whatsnew/2.4.html)).562- Built-in [`set()`](https://python-all.ru/3.1/library/stdtypes.html#set) and [`frozenset()`](https://python-all.ru/3.1/library/stdtypes.html#frozenset) types were added ([**PEP 218**](https://python-all.ru/3.1/whatsnew/2.4.html)). Other new built-ins include the `reversed(seq)()` function ([**PEP 322**](https://python-all.ru/3.1/whatsnew/2.4.html)).563- Добавлены генераторные выражения ([**PEP 289**](https://python-all.ru/3.1/whatsnew/2.4.html)).564- Некоторые числовые выражения больше не возвращают значения, ограниченные 32 или 64 битами ([**PEP 237**](https://python-all.ru/3.1/whatsnew/2.4.html)).565- Теперь можно заключать список имён в круглые скобки в инструкции `from module import names` ([**PEP 328**](https://python-all.ru/3.1/whatsnew/2.4.html)).566- Метод [`dict.update()`](https://python-all.ru/3.1/library/stdtypes.html#dict.update) теперь принимает те же формы аргументов, что и конструктор [`dict`](https://python-all.ru/3.1/library/stdtypes.html#dict). Это включает любое отображение, любую итерируемую последовательность пар ключ/значение и именованные аргументы. (Автор – Raymond Hettinger.)567- Строковые методы `ljust()`, `rjust()` и `center()` теперь принимают необязательный аргумент для указания символа заполнения, отличного от пробела. (Автор – Raymond Hettinger.)568- Строки также обзавелись методом `rsplit()`, который работает как метод `split()`, но разбивает строку с конца. (Автор – Sean Reifschneider.)569570  ```python571  >>> 'www.python.org'.split('.', 1)572  ['www', 'python.org']573  'www.python.org'.rsplit('.', 1)574  ['www.python', 'org']575  ```576- Три именованных параметра: *cmp*, *key* и *reverse* – были добавлены в метод `sort()` списков. Эти параметры упрощают некоторые распространённые варианты использования `sort()`. Все эти параметры необязательны.577578  Для параметра *cmp* значением должна быть функция сравнения, которая принимает два параметра и возвращает -1, 0 или +1 в зависимости от результата сравнения. Затем эта функция будет использоваться для сортировки списка. Ранее это был единственный параметр, который можно было передать в `sort()`.579580  *key* должна быть функцией с одним параметром, которая принимает элемент списка и возвращает ключ сравнения для этого элемента. Затем список сортируется с использованием ключей сравнения. Следующий пример сортирует список без учёта регистра:581582  ```python583  >>> L = ['A', 'b', 'c', 'D']584  >>> L.sort()                 # сортировка с учётом регистра585  >>> L586  ['A', 'D', 'b', 'c']587  >>> # использование параметра 'key' для сортировки списка588  >>> L.sort(key=lambda x: x.lower())589  >>> L590  ['A', 'b', 'c', 'D']591  >>> # старый способ592  >>> L.sort(cmp=lambda x,y: cmp(x.lower(), y.lower()))593  >>> L594  ['A', 'b', 'c', 'D']595  ```596597  Последний пример, в котором используется параметр *cmp*, представляет старый способ выполнения сортировки без учёта регистра. Он работает, но работает медленнее, чем использование параметра *key*. Использование *key* вызывает метод `lower()` один раз для каждого элемента списка, в то время как использование *cmp* вызывает его дважды для каждого сравнения, поэтому использование *key* экономит вызовы метода `lower()`.598599  Для простых ключевых функций и функций сравнения часто можно избежать использования выражения [`lambda`](https://python-all.ru/3.1/reference/expressions.html#lambda), используя вместо этого несвязанный метод. Например, приведённую выше сортировку без учёта регистра лучше всего записать так:600601  ```python602  >>> L.sort(key=str.lower)603  >>> L604  ['A', 'b', 'c', 'D']605  ```606607  Наконец, параметр *reverse* принимает булево значение. Если значение истинно, список будет отсортирован в обратном порядке. Вместо `L.sort() ; L.reverse()` теперь можно написать `L.sort(reverse=True)`.608609  Теперь гарантируется, что результаты сортировки устойчивы. Это означает, что две записи с равными ключами будут возвращены в том же порядке, в котором они поступили на вход. Например, можно отсортировать список людей по имени, а затем отсортировать список по возрасту, в результате получится список, отсортированный по возрасту, где люди с одинаковым возрастом находятся в порядке, отсортированном по имени.610611  (Все изменения в `sort()` предоставлены Рэймондом Хеттингером.)612- Появилась новая встроенная функция `sorted(iterable)()`, которая работает как метод `list.sort()`, изменяющий список на месте, но может использоваться в выражениях. Отличия:613- входными данными может быть любой итерируемый объект;614- сортируется новосозданная копия, оригинал остаётся нетронутым; и615- выражение возвращает новую отсортированную копию616617  ```python618  >>> L = [9,7,8,3,2,4,1,6,5]619  >>> [10+i for i in sorted(L)]       # можно использовать в списковом включении620  [11, 12, 13, 14, 15, 16, 17, 18, 19]621  >>> L                               # оригинал остаётся неизменным622  [9,7,8,3,2,4,1,6,5]623  >>> sorted('Monty Python')          # любой итерируемый объект может быть входным624  [' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y']625626  >>> # вывести содержимое словаря, отсортированное по ключам627  >>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5)628  >>> for k, v in sorted(colormap.iteritems()):629  ...     print k, v630  ...631  black 4632  blue 2633  green 3634  red 1635  yellow 5636  ```637638  (Автор: Raymond Hettinger.)639- Целочисленные операции больше не будут вызывать предупреждение `OverflowWarning`. Предупреждение `OverflowWarning` исчезнет в Python 2.5.640- Интерпретатор получил новый ключ [*-m*](https://python-all.ru/3.1/using/cmdline.html#cmdoption-trace-m), который принимает имя, ищет соответствующий модуль в `sys.path` и запускает его как сценарий. Например, теперь можно запустить профилировщик Python командой `python -m profile`. (Предоставлено Ником Когланом.)641- Функции `eval(expr, globals, locals)()` и `execfile(filename, globals, locals)()`, а также инструкция `exec` теперь принимают любой тип отображения для параметра *locals*. Ранее это должен был быть обычный словарь Python. (Автор: Raymond Hettinger.)642- Встроенная функция [`zip()`](https://python-all.ru/3.1/library/functions.html#zip) и `itertools.izip()` теперь возвращают пустой список, если вызваны без аргументов. Раньше они вызывали исключение [`TypeError`](https://python-all.ru/3.1/library/exceptions.html#TypeError). Это делает их более пригодными для использования со списками аргументов переменной длины:643644  ```python645  >>> def transpose(array):646  ...    return zip(*array)647  ...648  >>> transpose([(1,2,3), (4,5,6)])649  [(1, 4), (2, 5), (3, 6)]650  >>> transpose([])651  []652  ```653654  (Автор: Raymond Hettinger.)655- При возникновении ошибки во время импорта модуля частично инициализированный объект модуля больше не остаётся в `sys.modules`. Оставшийся неполный объект модуля мог бы ввести в заблуждение последующие импорты того же модуля, заставляя их считаться успешными, что приводило к запутанным ошибкам. (Исправлено Тимом Питерсом.)656- [`None`](https://python-all.ru/3.1/library/constants.html#None) теперь является константой; код, присваивающий новое значение имени `None`, теперь вызывает синтаксическую ошибку. (Предоставлено Рэймондом Хеттингером.)657658### Оптимизации659660- Внутренние циклы для нарезки списков и кортежей были оптимизированы и теперь работают примерно на треть быстрее. Внутренние циклы для словарей также были оптимизированы, что привело к повышению производительности `keys()`, `values()`, `items()`, `iterkeys()`, `itervalues()` и `iteritems()`. (Предоставлено Рэймондом Хеттингером.)661- Механизм увеличения и уменьшения списков был оптимизирован по скорости и эффективности использования памяти. Добавление и извлечение элементов из списков теперь выполняется быстрее благодаря более эффективным путям выполнения и менее частому использованию системной функции `realloc()`. Списковые включения также выигрывают. Метод `list.extend()` также был оптимизирован и больше не преобразует свой аргумент во временный список перед расширением основного списка. (Предоставлено Рэймондом Хеттингером.)662- [`list()`](https://python-all.ru/3.1/library/functions.html#list), [`tuple()`](https://python-all.ru/3.1/library/functions.html#tuple), [`map()`](https://python-all.ru/3.1/library/functions.html#map), [`filter()`](https://python-all.ru/3.1/library/functions.html#filter) и [`zip()`](https://python-all.ru/3.1/library/functions.html#zip) теперь работают в несколько раз быстрее с аргументами, не являющимися последовательностями, которые предоставляют метод [`__len__()`](https://python-all.ru/3.1/reference/datamodel.html#object.__len__). (Предоставлено Рэймондом Хеттингером.)663- Методы `list.__getitem__()`, `dict.__getitem__()` и `dict.__contains__()` теперь реализованы как объекты `method_descriptor`, а не `wrapper_descriptor`. Такая форма доступа удваивает их производительность и делает их более подходящими для передачи в функции: `map(mydict.__getitem__, keylist)`. (Автор: Raymond Hettinger.)664- Добавлен новый опкод `LIST_APPEND`, который упрощает генерируемый байт-код для списковых включений и ускоряет их примерно на треть. (Предоставлено Рэймондом Хеттингером.)665- Оптимизатор байткода на маленьких окнах (peephole) был улучшен для создания более короткого и быстрого байткода; примечательно, что результирующий байткод стал более читаемым. (Улучшено Raymond Hettinger.)666- Конкатенация строк в операторах вида `s = s + "abc"` и `s += "abc"` теперь выполняется более эффективно в определённых условиях. Эта оптимизация не будет присутствовать в других реализациях Python, таких как Jython, поэтому не стоит на неё полагаться; для эффективного склеивания большого количества строк по-прежнему рекомендуется использовать метод строк `join()`. (Предоставлено Армином Риго.)667668Итог оптимизаций в версии 2.4: Python 2.4 выполняет тест pystone примерно на 5% быстрее, чем Python 2.3, и на 35% быстрее, чем Python 2.2. (pystone – не самый удачный тест, но это наиболее распространённое измерение производительности Python. Ваши собственные приложения могут получить от Python 2.4 больший или меньший прирост.)669670## Новые, улучшенные и устаревшие модули671672Как обычно, стандартная библиотека Python получила ряд улучшений и исправлений ошибок. Вот частичный список наиболее заметных изменений, отсортированный по модулям в алфавитном порядке. За полным списком изменений обращайтесь к файлу `Misc/NEWS` в дереве исходных текстов, или просмотрите журналы CVS для получения всех подробностей.673674- Функция `loop()` модуля [`asyncore`](https://python-all.ru/3.1/library/asyncore.html#module-asyncore) теперь имеет параметр *count*, который позволяет выполнять ограниченное количество проходов цикла опроса. По умолчанию цикл по-прежнему выполняется бесконечно.675- Модуль [`base64`](https://python-all.ru/3.1/library/base64.html#module-base64) теперь имеет более полную поддержку RFC 3548 для кодирования и декодирования Base64, Base32 и Base16, включая необязательное преобразование регистра и необязательные альтернативные алфавиты. (Предоставлено Барри Уорсо.)676- Модуль [`bisect`](https://python-all.ru/3.1/library/bisect.html#module-bisect) теперь имеет реализацию на C для повышения производительности. (Предоставлено Дмитрием Васильевым.)677- Коллекции восточноазиатских кодеков CJKCodecs, поддерживаемые Hye-Shik Chang, были интегрированы в версию 2.4. Новые кодировки:678- Китай (КНР): gb2312, gbk, gb18030, big5hkscs, hz679- Китай (Тайвань): big5, cp950680- **Японский: cp932, euc-jis-2004, euc-jp, euc-jisx0213, iso-2022-jp,**681682  iso-2022-jp-1, iso-2022-jp-2, iso-2022-jp-3, iso-2022-jp-ext, iso-2022-jp-2004, shift-jis, shift-jisx0213, shift-jis-2004683- Корейский: cp949, euc-kr, johab, iso-2022-kr684- Были добавлены некоторые другие новые кодировки: HP Roman8, ISO\_8859-11, ISO\_8859-16, PCTP-154 и TIS-620.685- Кодеки UTF-8 и UTF-16 теперь лучше справляются с получением частичных входных данных. Раньше класс `StreamReader` пытался прочитать больше данных, что делало невозможным возобновление декодирования из потока. Теперь метод `read()` будет возвращать столько данных, сколько может, а последующие вызовы будут возобновлять декодирование с того места, где остановились предыдущие. (Реализовано Вальтером Дёрвальдом.)686- Появился новый модуль [`collections`](https://python-all.ru/3.1/library/collections.html#module-collections) для различных специализированных типов коллекций. В настоящее время он содержит только один тип – `deque`, двустороннюю очередь, которая эффективно поддерживает добавление и удаление элементов с любого конца:687688  ```python689  >>> from collections import deque690  >>> d = deque('ghi')        # создать новый deque с тремя элементами691  >>> d.append('j')           # добавить новый элемент справа692  >>> d.appendleft('f')       # добавить новый элемент слева693  >>> d                       # показать представление deque694  deque(['f', 'g', 'h', 'i', 'j'])695  >>> d.pop()                 # вернуть и удалить правый элемент696  'j'697  >>> d.popleft()             # вернуть и удалить левый элемент698  'f'699  >>> list(d)                 # вывести содержимое deque700  ['g', 'h', 'i']701  >>> 'h' in d                # поиск в deque702  True703  ```704705  Некоторые модули, такие как `Queue` и [`threading`](https://python-all.ru/3.1/library/threading.html#module-threading), теперь используют [`collections.deque`](https://python-all.ru/3.1/library/collections.html#collections.deque) для повышения производительности. (Предоставлено Рэймондом Хеттингером.)706- Классы `ConfigParser` были немного улучшены. Метод `read()` теперь возвращает список файлов, которые были успешно обработаны, а метод [`set()`](https://python-all.ru/3.1/library/stdtypes.html#set) вызывает [`TypeError`](https://python-all.ru/3.1/library/exceptions.html#TypeError), если ему передан аргумент *value*, не являющийся строкой. (Предоставлено Джоном Бельмонте и Дэвидом Гуджером.)707- Модуль [`curses`](https://python-all.ru/3.1/library/curses.html#module-curses) теперь поддерживает расширение ncurses `use_default_colors()`. На платформах, где терминал поддерживает прозрачность, это позволяет использовать прозрачный фон. (Предоставлено Йоргом Леманом.)708- Модуль [`difflib`](https://python-all.ru/3.1/library/difflib.html#module-difflib) теперь включает класс `HtmlDiff`, который создаёт HTML-таблицу для параллельного сравнения двух версий текста. (Предоставлено Дэном Гассом.)709- Пакет [`email`](https://python-all.ru/3.1/library/email.html#module-email) был обновлён до версии 3.0, в которой удалены различные устаревшие API и прекращена поддержка Python версий ниже 2.3. Версия 3.0 пакета использует новый инкрементальный парсер для MIME-сообщений, доступный в модуле `email.FeedParser`. Новый парсер не требует чтения всего сообщения в память и не вызывает исключений, если сообщение имеет неправильный формат; вместо этого все проблемы записываются в атрибут `defect` сообщения. (Разработано Энтони Бакстером, Барри Уорсо, Томасом Воутерсом и другими.)710- Модуль [`heapq`](https://python-all.ru/3.1/library/heapq.html#module-heapq) был переписан на C. Полученное десятикратное увеличение скорости делает модуль пригодным для обработки больших объёмов данных. Кроме того, в модуле появились две новые функции `nlargest()` и `nsmallest()`, которые используют кучи для поиска N наибольших или наименьших значений в наборе данных без затрат на полную сортировку. (Предоставлено Рэймондом Хеттингером.)711- Модуль `httplib` теперь содержит константы для HTTP-статусов, определённых в различных RFC-документах, связанных с HTTP. Константы имеют такие имена, как `OK`, `CREATED`, `CONTINUE` и `MOVED_PERMANENTLY`; используйте pydoc, чтобы получить полный список. (Предоставлено Эндрю Эландом.)712- Модуль [`imaplib`](https://python-all.ru/3.1/library/imaplib.html#module-imaplib) теперь поддерживает команду IMAP THREAD (предоставлено Ивом Дионом) и новые методы `deleteacl()` и `myrights()` (предоставлено Арно Мазеном).713- Модуль [`itertools`](https://python-all.ru/3.1/library/itertools.html#module-itertools) обзавёлся функцией `groupby(iterable[, *func*])()`. *iterable* – это объект, по которому можно итерироваться, чтобы получить поток элементов, а необязательный параметр *func* – это функция, принимающая элемент и возвращающая значение ключа; если он опущен, ключом является сам элемент. Затем `groupby()` группирует элементы в подпоследовательности с совпадающими значениями ключа и возвращает серию кортежей из двух элементов, содержащих значение ключа и итератор по подпоследовательности.714715  Вот пример для наглядности. Функция *key* просто возвращает, чётное число или нечётное, поэтому `groupby()` возвращает последовательные группы чётных или нечётных чисел.716717  ```python718  >>> import itertools719  >>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14]720  >>> for key_val, it in itertools.groupby(L, lambda x: x % 2):721  ...    print key_val, list(it)722  ...723  0 [2, 4, 6]724  1 [7]725  0 [8]726  1 [9, 11]727  0 [12, 14]728  >>>729  ```730731  `groupby()` обычно применяется к отсортированным данным. Логика `groupby()` похожа на фильтр `uniq` в Unix, что удобно для удаления, подсчёта или поиска дубликатов:732733  ```python734  >>> word = 'abracadabra'735  >>> letters = sorted(word)   # преобразовать строку в отсортированный список букв736  >>> letters737  ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r']738  >>> for k, g in itertools.groupby(letters):739  ...    print k, list(g)740  ...741  a ['a', 'a', 'a', 'a', 'a']742  b ['b', 'b']743  c ['c']744  d ['d']745  r ['r', 'r']746  >>> # вывести уникальные буквы747  >>> [k for k, g in groupby(letters)]748  ['a', 'b', 'c', 'd', 'r']749  >>> # подсчитать количество вхождений букв750  >>> [(k, len(list(g))) for k, g in groupby(letters)]751  [('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]752  ```753754  (Добавлено Hye-Shik Chang.)755- Модуль [`itertools`](https://python-all.ru/3.1/library/itertools.html#module-itertools) также получил функцию с именем `tee(iterator, N)()`, которая возвращает *N* независимых итераторов, копирующих *iterator*. Если *N* опущен, по умолчанию используется 2.756757  ```python758  >>> L = [1,2,3]759  >>> i1, i2 = itertools.tee(L)760  >>> i1,i2761  (<itertools.tee object at 0x402c2080>, <itertools.tee object at 0x402c2090>)762  >>> list(i1)               # исчерпать первый итератор763  [1, 2, 3]764  >>> list(i2)               # исчерпать второй итератор765  [1, 2, 3]766  ```767768  Обратите внимание: `tee()` вынужден хранить копии значений, возвращаемых итератором; в худшем случае может потребоваться сохранить их все. Поэтому эту функцию следует использовать с осторожностью, если ведущий итератор может сильно опередить ведомый при работе с длинной входной последовательностью. Если разрыв велик, лучше вместо этого применить [`list()`](https://python-all.ru/3.1/library/functions.html#list). Когда итераторы движутся близко друг к другу, `tee()` идеален. Возможные применения: закладки, скользящее окно или итераторы с упреждающим чтением. (Автор – Raymond Hettinger.)769- В модуль [`locale`](https://python-all.ru/3.1/library/locale.html#module-locale) добавлено несколько функций, например `bind_textdomain_codeset()` для указания конкретной кодировки и семейство функций `l*gettext()`, возвращающих сообщения в выбранной кодировке. (Автор – Gustavo Niemeyer.)770- В функцию `basicConfig()` пакета [`logging`](https://python-all.ru/3.1/library/logging.html#module-logging) добавлены именованные аргументы для упрощения настройки логирования. По умолчанию сообщения выводятся в стандартный поток ошибок, но с помощью различных именованных аргументов можно указать конкретный файл, изменить формат или установить уровень логирования. Например:771772  ```python773  import logging774  logging.basicConfig(filename='/var/log/application.log',775      level=0,  # записать все сообщения в лог776      format='%(levelname):%(process):%(thread):%(message)')777  ```778779  Другие дополнения пакета [`logging`](https://python-all.ru/3.1/library/logging.html#module-logging) включают удобный метод `log(level, msg)()`, а также класс `TimedRotatingFileHandler`, который ротирует файлы журналов через заданные интервалы времени. В модуле уже был `RotatingFileHandler`, ротирующий журналы, когда файл превышал определённый размер. Оба класса наследуются от нового класса `BaseRotatingHandler`, который можно использовать для реализации других ротирующих обработчиков.780781  (Изменения внесены Vinay Sajip.)782- Модуль [`marshal`](https://python-all.ru/3.1/library/marshal.html#module-marshal) теперь при распаковке структуры данных разделяет интернированные строки. Это может уменьшить размер некоторых pickle-строк, но главный эффект – значительное уменьшение размера файлов `.pyc`. (Автор – Martin von Löwis.)783- Класс `NNTP` модуля [`nntplib`](https://python-all.ru/3.1/library/nntplib.html#module-nntplib) обзавёлся методами `description()` и `descriptions()` для получения описаний групп новостей – как для одной группы, так и для диапазона групп. (Автор – Jürgen A. Erhard.)784- В модуль [`operator`](https://python-all.ru/3.1/library/operator.html#module-operator) были добавлены две новые функции: `attrgetter(attr)()` и `itemgetter(index)()`. Обе функции возвращают вызываемые объекты, которые принимают один аргумент и возвращают соответствующий атрибут или элемент; эти вызываемые объекты отлично подходят для извлечения данных при использовании с [`map()`](https://python-all.ru/3.1/library/functions.html#map) или [`sorted()`](https://python-all.ru/3.1/library/functions.html#sorted). Например:785786  ```python787  >>> L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)]788  >>> map(operator.itemgetter(0), L)789  ['c', 'd', 'a', 'b']790  >>> map(operator.itemgetter(1), L)791  [2, 1, 4, 3]792  >>> sorted(L, key=operator.itemgetter(1)) # отсортировать список по второму элементу кортежа793  [('d', 1), ('c', 2), ('b', 3), ('a', 4)]794  ```795796  (Автор: Raymond Hettinger.)797- Модуль [`optparse`](https://python-all.ru/3.1/library/optparse.html#module-optparse) был обновлён в разных направлениях. Теперь он передаёт свои сообщения через [`gettext.gettext()`](https://python-all.ru/3.1/library/gettext.html#gettext.gettext), что позволяет интернационализировать справочные сообщения и сообщения об ошибках Optik. В справочные сообщения для опций теперь можно включать строку `'%default'`, которая будет заменена значением опции по умолчанию. (Автор – Greg Ward.)798- В долгосрочной перспективе модуль `rfc822` планируется объявить устаревшим в одной из будущих версий Python в пользу пакета [`email`](https://python-all.ru/3.1/library/email.html#module-email). С этой целью функция `email.Utils.formatdate()` была изменена так, чтобы её можно было использовать как замену `rfc822.formatdate()`. При написании нового кода для обработки электронной почты стоит иметь это в виду. (Изменение реализовано Anthony Baxter.)799- В модуль [`os`](https://python-all.ru/3.1/library/os.html#module-os) добавлена новая функция `urandom(n)()`, возвращающая строку из *n* байт случайных данных. Эта функция предоставляет доступ к платформенно-зависимым источникам случайности, таким как `/dev/urandom` в Linux или CryptoAPI в Windows. (Автор: Trevor Perrin.)800- Ещё одна новая функция: `os.path.lexists(path)()` возвращает истину, если файл, указанный в *path*, существует, независимо от того, является ли он символической ссылкой. Это отличается от существующей функции `os.path.exists(path)()`, которая возвращает ложь, если *path* – это символическая ссылка, указывающая на несуществующий объект. (Автор: Beni Cherniavsky.)801- В модуль [`posix`](https://python-all.ru/3.1/library/posix.html#module-posix), лежащий в основе модуля [`os`](https://python-all.ru/3.1/library/os.html#module-os), добавлена новая функция `getsid()`. (Автор – J. Raynor.)802- Модуль [`poplib`](https://python-all.ru/3.1/library/poplib.html#module-poplib) теперь поддерживает POP через SSL. (Автор – Hector Urtubia.)803- Модуль [`profile`](https://python-all.ru/3.1/library/profile.html#module-profile) теперь может профилировать функции-расширения на C. (Автор – Nick Bastin.)804- Модуль [`random`](https://python-all.ru/3.1/library/random.html#module-random) имеет новый метод `getrandbits(N)()`, который возвращает длинное целое длиной в *N* бит. Существующий метод `randrange()` теперь использует `getrandbits()`, где это уместно, что делает генерацию произвольно больших случайных чисел более эффективной. (Автор: Raymond Hettinger.)805- Язык регулярных выражений, поддерживаемый модулем [`re`](https://python-all.ru/3.1/library/re.html#module-re), расширен простыми условными выражениями, записываемыми как `(?(group)A|B)`. *group* – это либо числовой идентификатор группы, либо имя группы, определённое с помощью `(?P<group>...)` ранее в выражении. Если указанная группа совпала, со строкой сопоставляется шаблон *A*; если группа не совпала, используется шаблон *B*. (Автор – Gustavo Niemeyer.)806- Модуль [`re`](https://python-all.ru/3.1/library/re.html#module-re) также больше не является рекурсивным – благодаря огромной работе Густаво Нимейера. В рекурсивном движке регулярных выражений некоторые шаблоны приводили к потреблению большого объёма памяти в стеке C, что могло вызвать переполнение стека. Например, если сопоставить строку из 30000 символов `a` с выражением `(a|b)+`, на каждый символ расходовался один стековый фрейм. Python 2.3 пытался проверять переполнение стека и возбуждать исключение [`RuntimeError`](https://python-all.ru/3.1/library/exceptions.html#RuntimeError), но некоторые шаблоны могли обойти проверку, и при невезении Python падал с segfault. Движок регулярных выражений Python 2.4 обрабатывает этот шаблон без проблем.807- Модуль [`signal`](https://python-all.ru/3.1/library/signal.html#module-signal) теперь выполняет более строгую проверку ошибок для параметров функции [`signal.signal()`](https://python-all.ru/3.1/library/signal.html#signal.signal). Например, нельзя установить обработчик на сигнал `SIGKILL`; предыдущие версии Python молча принимали это, но 2.4 возбудит исключение [`RuntimeError`](https://python-all.ru/3.1/library/exceptions.html#RuntimeError).808- В модуль [`socket`](https://python-all.ru/3.1/library/socket.html#module-socket) были добавлены две новые функции. `socketpair()` возвращает пару соединённых сокетов, а `getservbyport(port)()` ищет имя службы по заданному номеру порта. (Авторы: Dave Cole и Barry Warsaw.)809- Функция `sys.exitfunc()` объявлена устаревшей. В коде следует использовать существующий модуль [`atexit`](https://python-all.ru/3.1/library/atexit.html#module-atexit), который корректно обрабатывает вызов нескольких функций завершения. Со временем `sys.exitfunc()` станет чисто внутренним интерфейсом, доступным только через [`atexit`](https://python-all.ru/3.1/library/atexit.html#module-atexit).810- Модуль [`tarfile`](https://python-all.ru/3.1/library/tarfile.html#module-tarfile) теперь по умолчанию создаёт tar-файлы в формате GNU. (Автор: Lars Gustaebel.)811- Модуль [`threading`](https://python-all.ru/3.1/library/threading.html#module-threading) теперь предлагает элегантно простой способ поддержки данных, локальных для потока. В модуле содержится класс `local`, значения атрибутов которого локальны для разных потоков.812813  ```python814  import threading815816  data = threading.local()817  data.number = 42818  data.url = ('www.python.org', 80)819  ```820821  Другие потоки могут присваивать и получать собственные значения для атрибутов `number` и `url`. От `local` можно создавать подклассы для инициализации атрибутов или добавления методов. (Автор – Jim Fulton.)822- Модуль [`timeit`](https://python-all.ru/3.1/library/timeit.html#module-timeit) теперь автоматически отключает периодическую сборку мусора во время цикла замера. Это изменение делает последовательные замеры более сопоставимыми. (Автор – Raymond Hettinger.)823- Модуль [`weakref`](https://python-all.ru/3.1/library/weakref.html#module-weakref) теперь поддерживает более широкий спектр объектов, включая функции Python, экземпляры классов, множества, неизменяемые множества (frozenset), двусторонние очереди (deque), массивы, файлы, сокеты и объекты шаблонов регулярных выражений. (Автор – Raymond Hettinger.)824- Модуль `xmlrpclib` теперь поддерживает расширение multi-call для передачи нескольких XML-RPC-вызовов в одной HTTP-операции. (Автор – Brian Quinlan.)825- Модули `mpz`, `rotor` и `xreadlines` удалены.826827### cookielib828829Библиотека `cookielib` поддерживает обработку HTTP-куки на стороне клиента, подобно тому, как модуль `Cookie` поддерживает куки на стороне сервера. Куки хранятся в хранилищах (cookie jar); библиотека прозрачно сохраняет куки, предлагаемые веб-сервером, в хранилище и извлекает их оттуда при подключении к серверу. Как и в веб-браузерах, объекты политики определяют, принимать ли куки.830831Для сохранения куки между сеансами предоставляются две реализации хранилищ: одна хранит куки в формате Netscape, чтобы приложения могли использовать файлы куки Mozilla или Lynx, а другая хранит куки в том же формате, что и библиотека Perl libwww.832833`urllib2` был изменён для взаимодействия с `cookielib`: `HTTPCookieProcessor` управляет хранилищем куки, которое используется при доступе к URL.834835Этот модуль был предоставлен Джоном Дж. Ли.836837### doctest838839Модуль [`doctest`](https://python-all.ru/3.1/library/doctest.html#module-doctest) претерпел значительный рефакторинг благодаря Эдварду Лоперу и Тиму Питерсу. Тестирование по-прежнему может быть таким же простым, как запуск [`doctest.testmod()`](https://python-all.ru/3.1/library/doctest.html#doctest.testmod), но рефакторинг позволяет настраивать работу модуля различными способами.840841Новый класс `DocTestFinder` извлекает тесты из docstrings заданного объекта:842843```python844def f (x, y):845    """>>> f(2,2)8464847>>> f(3,2)8486849    """850    return x*y851852finder = doctest.DocTestFinder()853854# получить список экземпляров DocTest855tests = finder.find(f)856```857858Затем новый класс `DocTestRunner` запускает отдельные тесты и может сформировать сводку результатов:859860```python861runner = doctest.DocTestRunner()862for t in tests:863    tried, failed = runner.run(t)864865runner.summarize(verbose=1)866```867868Приведённый выше пример даёт следующий вывод:869870```python8711 items passed all tests:872   2 tests in f8732 tests in 1 items.8742 passed and 0 failed.875Test passed.876```877878`DocTestRunner` использует экземпляр класса `OutputChecker` для сравнения ожидаемого вывода с фактическим. Этот класс принимает ряд различных флагов, настраивающих его поведение; опытные пользователи также могут написать полностью новый подкласс `OutputChecker`.879880Стандартная проверка вывода предоставляет ряд удобных возможностей. Например, с флагом опции [`doctest.ELLIPSIS`](https://python-all.ru/3.1/library/doctest.html#doctest.ELLIPSIS) многоточие (`...`) в ожидаемом выводе совпадает с любой подстрокой, что упрощает обработку выводов, которые незначительно различаются:881882```python883def o (n):884    """>>> o(1)885<__main__.C instance at 0x...>886>>>887"""888```889890Ещё одна специальная строка, `<BLANKLINE>`, соответствует пустой строке:891892```python893def p (n):894    """>>> p(1)895<BLANKLINE>896>>>897"""898```899900Ещё одна новая возможность – отображение вывода в стиле diff с помощью флагов опций [`doctest.REPORT_UDIFF`](https://python-all.ru/3.1/library/doctest.html#doctest.REPORT_UDIFF) (унифицированные diff), [`doctest.REPORT_CDIFF`](https://python-all.ru/3.1/library/doctest.html#doctest.REPORT_CDIFF) (контекстные diff) или [`doctest.REPORT_NDIFF`](https://python-all.ru/3.1/library/doctest.html#doctest.REPORT_NDIFF) (дельта-стиль). Например:901902```python903def g (n):904    """>>> g(4)905здесь906есть907a908длинный909>>>"""910    L = 'here is a rather lengthy list of words'.split()911    for word in L[:n]:912        print word913```914915При запуске тестов вышеуказанной функции с указанием [`doctest.REPORT_UDIFF`](https://python-all.ru/3.1/library/doctest.html#doctest.REPORT_UDIFF) получается следующий вывод:916917```python918**********************************************************************919File "t.py", line 15, in g920Failed example:921    g(4)922Differences (unified diff with -expected +actual):923    @@ -2,3 +2,3 @@924     is925     a926    -lengthy927    +rather928**********************************************************************929```930931## Изменения в сборке и C API932933Некоторые из изменений в процессе сборки Python и в C API:934935- Было добавлено три новых удобных макроса для распространённых возвращаемых значений из функций расширения: [`Py_RETURN_NONE`](https://python-all.ru/3.1/c-api/none.html#Py_RETURN_NONE), [`Py_RETURN_TRUE`](https://python-all.ru/3.1/c-api/bool.html#Py_RETURN_TRUE) и [`Py_RETURN_FALSE`](https://python-all.ru/3.1/c-api/bool.html#Py_RETURN_FALSE). (Автор: Brett Cannon.)936- Ещё один новый макрос, `Py_CLEAR(obj)`, уменьшает счётчик ссылок *obj* и устанавливает *obj* в нулевой указатель. (Автор: Jim Fulton.)937- Новая функция `PyTuple_Pack(N, obj1, obj2, ..., objN)()` создаёт кортежи из списка аргументов переменной длины, состоящего из объектов Python. (Автор: Raymond Hettinger.)938- Новая функция `PyDict_Contains(d, k)()` реализует быстрый поиск в словаре, не скрывая исключения, возникающие в процессе поиска. (Автор: Raymond Hettinger.)939- Макрос `Py_IS_NAN(X)` возвращает 1, если его аргумент типа float или double *X* является NaN. (Автор: Tim Peters.)940- Код на C может избежать ненужной блокировки, используя новую функцию [`PyEval_ThreadsInitialized()`](https://python-all.ru/3.1/c-api/init.html#PyEval_ThreadsInitialized), чтобы определить, выполнялись ли какие-либо операции с потоками. Если эта функция возвращает false, операции блокировки не нужны. (Автор: Nick Coghlan.)941- Новая функция [`PyArg_VaParseTupleAndKeywords()`](https://python-all.ru/3.1/c-api/arg.html#PyArg_VaParseTupleAndKeywords) аналогична [`PyArg_ParseTupleAndKeywords()`](https://python-all.ru/3.1/c-api/arg.html#PyArg_ParseTupleAndKeywords), но принимает `va_list` вместо нескольких аргументов. (Автор: Greg Chapman.)942- Новый флаг метода `METH_COEXISTS` позволяет функции, определённой в слотах, сосуществовать с [`PyCFunction`](https://python-all.ru/3.1/c-api/structures.html#PyCFunction) с тем же именем. Это может вдвое сократить время доступа к методу, такому как `set.__contains__()`. (Автор: Raymond Hettinger.)943- Python теперь можно собрать с дополнительным профилированием самого интерпретатора, предназначенным в помощь разработчикам ядра Python. Передача *----enable-profiling* скрипту **configure** позволит профилировать интерпретатор с помощью **gprof**, а передача ключа *----with-tsc* включает профилирование с использованием регистра счётчика временных меток Pentium. Обратите внимание, что ключ *----with-tsc* назван не совсем точно, поскольку функция профилирования также работает на платформе PowerPC, хотя в этой архитектуре процессора этот регистр не называют «регистром TSC». (Автор: Jeremy Hylton.)944- Тип `tracebackobject` был переименован в `PyTracebackObject`.945946### Изменения, специфичные для платформ947948- Версия для Windows теперь собирается в MSVC++ 7.1, а также в версии 6. (Автор: Мартин фон Лёвис.)949950## Переход на Python 2.4951952В этом разделе перечислены описанные ранее изменения, которые могут потребовать изменения кода:953954- Сдвиги влево и шестнадцатеричные/восьмеричные константы, которые слишком велики, больше не вызывают [`FutureWarning`](https://python-all.ru/3.1/library/exceptions.html#FutureWarning) и не возвращают значение, ограниченное 32 или 64 битами; вместо этого они возвращают длинное целое.955- Целочисленные операции больше не будут вызывать предупреждение `OverflowWarning`. Предупреждение `OverflowWarning` исчезнет в Python 2.5.956- Встроенная функция [`zip()`](https://python-all.ru/3.1/library/functions.html#zip) и `itertools.izip()` теперь возвращают пустой список вместо возбуждения исключения [`TypeError`](https://python-all.ru/3.1/library/exceptions.html#TypeError), если вызваны без аргументов.957- Больше нельзя сравнивать экземпляры `date` и `datetime` из модуля [`datetime`](https://python-all.ru/3.1/library/datetime.html#module-datetime). Два экземпляра разных классов теперь всегда будут неравны, а операции относительного сравнения (`<`, `>`) будут вызывать [`TypeError`](https://python-all.ru/3.1/library/exceptions.html#TypeError).958- `dircache.listdir()` теперь передаёт исключения вызывающему коду вместо возврата пустых списков.959- `LexicalHandler.startDTD()` раньше получал общедоступный и системный идентификаторы в неправильном порядке. Это было исправлено; приложения, полагающиеся на неправильный порядок, необходимо исправить.960- [`fcntl.ioctl()`](https://python-all.ru/3.1/library/fcntl.html#fcntl.ioctl) теперь выдаёт предупреждение, если аргумент *mutate* опущен и это актуально.961- Модуль [`tarfile`](https://python-all.ru/3.1/library/tarfile.html#module-tarfile) теперь по умолчанию создаёт tar-файлы в формате GNU.962- При ошибке во время импорта модуля в `sys.modules` больше не остаётся частично инициализированный объект модуля.963- [`None`](https://python-all.ru/3.1/library/constants.html#None) теперь является константой; код, который присваивает новое значение имени `None`, теперь вызывает синтаксическую ошибку.964- Функция `signals.signal()` теперь возбуждает исключение [`RuntimeError`](https://python-all.ru/3.1/library/exceptions.html#RuntimeError) для некоторых недопустимых значений; ранее эти ошибки проходили незаметно. Например, больше нельзя установить обработчик на сигнал `SIGKILL`.965966## Благодарности967968Автор хотел бы поблагодарить следующих людей за предложения, исправления и помощь в работе над различными черновиками этой статьи: Koray Can, Hye-Shik Chang, Michael Dyck, Raymond Hettinger, Brian Hurt, Hamish Lawson, Fredrik Lundh, Sean Reifschneider, Sadruddin Rejeb.969