Содержание страницы
Что нового в Python 2.3¶What’s New in Python 2.3
| Автор: | A.M. Kuchling |
|---|
В этой статье описываются новые возможности Python 2.3. Python 2.3 был выпущен 29 июля 2003 года.
Основные темы Python 2.3 – это шлифовка некоторых возможностей, добавленных в 2.2, добавление различных мелких, но полезных улучшений в ядро языка и расширение стандартной библиотеки. Новая объектная модель, представленная в предыдущей версии, выиграла от 18 месяцев исправлений ошибок и оптимизационных усилий, которые повысили производительность классов нового стиля. Было добавлено несколько новых встроенных функций, таких как sum() и enumerate(). Оператор in теперь можно использовать для поиска подстрок (например, "ab" in "abc" возвращает True).
Некоторые из множества новых возможностей библиотеки включают логические типы, множества, кучи и типы даты/времени, возможность импортировать модули из ZIP-архивов, поддержку метаданных для долгожданного каталога Python, обновленную версию IDLE, а также модули для журналирования сообщений, переноса текста, разбора CSV-файлов, обработки параметров командной строки, использования баз данных BerkeleyDB... список новых и улучшенных модулей обширен.
Эта статья не пытается дать полную спецификацию новых возможностей, а предоставляет удобный обзор. За полными подробностями следует обращаться к документации по Python 2.3, такой как «Справочник по библиотеке Python» и «Руководство по языку Python». Чтобы понять полную реализацию и обоснование дизайна, следует обратиться к PEP для конкретной новой возможности.
PEP 218: Стандартный тип данных «множество»¶PEP 218: A Standard Set Datatype
Новый модуль sets содержит реализацию типа данных «множество». Класс Set предназначен для изменяемых множеств, в которые можно добавлять и удалять элементы. Класс ImmutableSet – для неизменяемых множеств, и экземпляры ImmutableSet поэтому могут использоваться в качестве ключей словаря. Множества построены поверх словарей, поэтому элементы множества должны быть хешируемыми.
Вот простой пример:
>>> import sets
>>> S = sets.Set([1,2,3])
>>> S
Set([1, 2, 3])
>>> 1 in S
True
>>> 0 in S
False
>>> S.add(5)
>>> S.remove(3)
>>> S
Set([1, 2, 5])
>>>
Объединение и пересечение множеств можно вычислить с помощью методов union() и intersection(); альтернативная запись использует побитовые операторы & и |. Изменяемые множества также имеют версии этих методов, изменяющие само множество: union_update() и intersection_update().
>>> S1 = sets.Set([1,2,3])
>>> S2 = sets.Set([4,5,6])
>>> S1.union(S2)
Set([1, 2, 3, 4, 5, 6])
>>> S1 | S2 # Альтернативная запись
Set([1, 2, 3, 4, 5, 6])
>>> S1.intersection(S2)
Set([])
>>> S1 & S2 # Альтернативная запись
Set([])
>>> S1.union_update(S2)
>>> S1
Set([1, 2, 3, 4, 5, 6])
>>>
Также можно вычислить симметрическую разность двух множеств. Это множество всех элементов объединения, которые не входят в пересечение. Другими словами, симметрическая разность содержит все элементы, которые находятся ровно в одном из множеств. Опять же, есть альтернативная запись (^) и версия, изменяющая само множество, с неуклюжим именем symmetric_difference_update().
>>> S1 = sets.Set([1,2,3,4])
>>> S2 = sets.Set([3,4,5,6])
>>> S1.symmetric_difference(S2)
Set([1, 2, 5, 6])
>>> S1 ^ S2
Set([1, 2, 5, 6])
>>>
Также есть методы issubset() и issuperset() для проверки, является ли одно множество подмножеством или надмножеством другого:
>>> S1 = sets.Set([1,2,3])
>>> S2 = sets.Set([2,3])
>>> S2.issubset(S1)
True
>>> S1.issubset(S2)
False
>>> S1.issuperset(S2)
True
>>>
См. также
- PEP 218 – Добавление встроенного типа объектов-множеств
- PEP написан Грегом В. Уилсоном. Реализован Грегом В. Уилсоном, Алексом Мартелли и GvR.
PEP 255: Простые генераторы¶PEP 255: Simple Generators
В Python 2.2 генераторы были добавлены как опциональная возможность, включаемая директивой from __future__ import generators. В версии 2.3 генераторы больше не нужно специально включать, они теперь присутствуют всегда; это означает, что yield теперь всегда является ключевым словом. Остальная часть этого раздела – копия описания генераторов из документа «What’s New in Python 2.2»; если вы читали его, когда выходил Python 2.2, можете пропустить остаток этого раздела.
Вам, несомненно, знакомо, как работают вызовы функций в Python или C. Когда вы вызываете функцию, она получает отдельное пространство имён, в котором создаются её локальные переменные. Когда функция достигает оператора return, локальные переменные уничтожаются, а полученное значение возвращается вызывающему коду. Последующий вызов той же функции получит новый набор локальных переменных. Но что, если бы локальные переменные не отбрасывались при выходе из функции? Что, если бы можно было возобновить выполнение функции с того места, где она остановилась? Именно это и предоставляют генераторы; их можно рассматривать как возобновляемые функции.
Вот простейший пример функции-генератора:
def generate_ints(N):
for i in range(N):
yield i
Для генераторов было введено новое ключевое слово yield. Любая функция, содержащая оператор yield, является генераторной функцией; это обнаруживается компилятором байт-кода Python, который соответственно компилирует такую функцию особым образом.
Когда вы вызываете генераторную функцию, она возвращает не одно значение; вместо этого она возвращает объект-генератор, поддерживающий протокол итератора. При выполнении оператора yield генератор выводит значение i, аналогично оператору return. Большое различие между yield и оператором return состоит в том, что при достижении yield состояние выполнения генератора приостанавливается, а локальные переменные сохраняются. При следующем вызове метода .next() генератора функция продолжит выполнение сразу после оператора yield. (По сложным причинам оператор yield не допускается внутри блока try оператора try...finally; прочитайте PEP 255 для полного объяснения взаимодействия между yield и исключениями.)
Вот пример использования генератора generate_ints():
>>> gen = generate_ints(3)
>>> gen
<generator object at 0x8117f90>
>>> gen.next()
0
>>> gen.next()
1
>>> gen.next()
2
>>> gen.next()
Traceback (most recent call last):
File "stdin", line 1, in ?
File "stdin", line 2, in generate_ints
StopIteration
Можно также написать for i in generate_ints(5), или a,b,c = generate_ints(3).
Внутри генераторной функции оператор return может использоваться только без значения и сигнализирует об окончании выдачи значений; после этого генератор не может вернуть больше значений. return со значением, например return 5, является синтаксической ошибкой внутри генераторной функции. Окончание результатов генератора также можно указать, возбудив StopIteration вручную или просто позволив потоку выполнения достичь конца функции.
Эффекта генераторов можно добиться вручную, написав собственный класс и сохранив все локальные переменные генератора как атрибуты экземпляра. Например, возврат списка целых чисел можно сделать, установив self.count в 0 и заставив метод next() увеличивать self.count и возвращать его. Однако для сколько-нибудь сложного генератора написание соответствующего класса было бы гораздо запутаннее. Lib/test/test_generators.py содержит ряд более интересных примеров. Простейший из них реализует обход дерева в порядке (in-order) с использованием генераторов рекурсивно.
# Рекурсивный генератор, порождающий листья дерева в порядке in-order.
def inorder(t):
if t:
for x in inorder(t.left):
yield x
yield t.label
for x in inorder(t.right):
yield x
Два других примера в Lib/test/test_generators.py дают решения задачи о N ферзях (размещение $N$ ферзей на доске $N \times N$ так, чтобы ни один ферзь не угрожал другому) и задачи о ходе коня (маршрут, который проводит коня через каждую клетку доски $N \times N$, не посещая ни одну клетку дважды).
Идея генераторов пришла из других языков программирования, особенно Icon (http://www.cs.arizona.edu/icon/), где идея генераторов является центральной. В Icon каждое выражение и вызов функции ведут себя как генератор. Один пример из «An Overview of the Icon Programming Language» по адресу http://www.cs.arizona.edu/icon/docs/ipd266.htm даёт представление о том, как это выглядит:
sentence := "Store it in the neighboring harbor"
if (i := find("or", sentence)) > 5 then write(i)
В Icon функция find() возвращает индексы, по которым встречается подстрока «or»: 3, 23, 33. В операторе if i сначала присваивается значение 3, но 3 меньше 5, поэтому сравнение не проходит, и Icon повторяет его со вторым значением 23. 23 больше 5, поэтому сравнение теперь успешно, и код выводит значение 23 на экран.
Python не заходит так далеко, как Icon, в принятии генераторов в качестве центральной концепции. Генераторы считаются частью ядра языка Python, но их изучение или использование не является обязательным; если они не решают никаких проблем, их можно смело игнорировать. Одна новая особенность интерфейса Python по сравнению с Icon заключается в том, что состояние генератора представлено в виде конкретного объекта (итератора), который можно передавать другим функциям или хранить в структуре данных.
См. также
- PEP 255 - Simple Generators
- Авторы: Нил Шеменауэр, Тим Питерс, Магнус Ли Хетланд. Реализовано в основном Нилом Шеменауэром и Тимом Питерсом, с дополнительными исправлениями от команды Python Labs.
PEP 263: Кодировки исходного кода¶PEP 263: Source Code Encodings
Файлы исходного кода Python теперь можно объявлять как файлы в различных кодировках символов. Кодировки объявляются путём включения специально отформатированного комментария в первую или вторую строку исходного файла. Например, файл в UTF-8 можно объявить с помощью:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
Без такого объявления кодировки по умолчанию используется 7-битная ASCII. Выполнение или импорт модулей, которые содержат строковые литералы с 8-битными символами и не имеют объявления кодировки, приведёт к тому, что Python 2.3 сгенерирует DeprecationWarning; в версии 2.4 это будет синтаксической ошибкой.
Объявление кодировки влияет только на строковые литералы Unicode, которые будут преобразованы в Unicode с использованием указанной кодировки. Обратите внимание, что идентификаторы Python по-прежнему ограничены символами ASCII, поэтому нельзя использовать имена переменных, содержащие символы за пределами обычных буквенно-цифровых.
См. также
- PEP 263 – Определение кодировок исходного кода Python
- Авторы: Marc-André Lemburg и Martin von Löwis; реализовано Suzuki Hisao и Martin von Löwis.
PEP 273: Импорт модулей из ZIP-архивов¶PEP 273: Importing Modules from ZIP Archives
Новый модуль zipimport добавляет поддержку импорта модулей из ZIP-архивов. Явно импортировать этот модуль не нужно; он будет импортирован автоматически, если имя ZIP-архива добавлено в sys.path. Например:
amk@nyman:~/src/python$ unzip -l /tmp/example.zip
Archive: /tmp/example.zip
Length Date Time Name
-------- ---- ---- ----
8467 11-26-02 22:30 jwzthreading.py
-------- -------
8467 1 file
amk@nyman:~/src/python$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32)
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip') # Add .zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'
>>>
Запись в sys.path теперь может быть именем ZIP-архива. ZIP-архив может содержать файлы любого типа, но импортировать можно только файлы с именами *.py, *.pyc или *.pyo. Если архив содержит только файлы *.py, Python не будет пытаться изменить архив, добавляя соответствующий файл *.pyc; это означает, что если ZIP-архив не содержит файлов *.pyc, импорт может быть довольно медленным.
Также можно указать путь внутри архива, чтобы импортировать только из подкаталога; например, путь /tmp/example.zip/lib/ будет импортировать только из подкаталога lib/ внутри архива.
См. также
- PEP 273 – Импорт модулей из Zip-архивов
- Автор: James C. Ahlstrom, он же предоставил реализацию. Python 2.3 следует спецификации из PEP 273, но использует реализацию, написанную Just van Rossum, которая применяет хуки импорта, описанные в PEP 302. См. раздел PEP 302: Новые хуки импорта для описания новых хуков импорта.
PEP 277: Поддержка имен файлов в Unicode для Windows NT¶PEP 277: Unicode file name support for Windows NT
В Windows NT, 2000 и XP система хранит имена файлов в виде строк Unicode. Традиционно Python представлял имена файлов как байтовые строки, что неудовлетворительно, так как делает некоторые имена файлов недоступными.
Python теперь позволяет использовать произвольные строки Unicode (в пределах ограничений файловой системы) для всех функций, ожидающих имена файлов, прежде всего для встроенной функции open(). Если строку Unicode передать в os.listdir(), Python теперь возвращает список строк Unicode. Новая функция os.getcwdu() возвращает текущий каталог в виде строки Unicode.
Байтовые строки по-прежнему работают как имена файлов, и в Windows Python будет прозрачно преобразовывать их в Unicode, используя кодировку mbcs.
Другие системы также допускают строки Unicode в качестве имён файлов, но преобразуют их в байтовые строки перед передачей системе, что может вызвать UnicodeError. Приложения могут проверить, поддерживаются ли произвольные строки Unicode в качестве имён файлов, проверив os.path.supports_unicode_filenames – логическое значение.
В MacOS os.listdir() теперь может возвращать имена файлов в Unicode.
См. также
- PEP 277 – Поддержка имен файлов в Unicode для Windows NT
- Автор: Neil Hodgson; реализовано Neil Hodgson, Martin von Löwis и Mark Hammond.
PEP 278: Универсальная поддержка символов новой строки¶PEP 278: Universal Newline Support
Три основные операционные системы, используемые сегодня, – это Microsoft Windows, Macintosh OS от Apple и различные производные Unix. Небольшое раздражение при кроссплатформенной работе заключается в том, что эти три платформы используют разные символы для обозначения концов строк в текстовых файлах. Unix использует перевод строки (символ ASCII 10), MacOS использует возврат каретки (символ ASCII 13), а Windows использует двухсимвольную последовательность: возврат каретки и перевод строки.
Файловые объекты Python теперь могут поддерживать соглашения об окончании строк, отличные от принятых на платформе, на которой выполняется Python. Открытие файла с режимом 'U' или 'rU' откроет файл для чтения в режиме универсальных новых строк (universal newlines). Все три соглашения об окончании строк будут преобразованы в '\n' в строках, возвращаемых различными файловыми методами, такими как read() и readline().
Поддержка универсальных новых строк также используется при импорте модулей и при выполнении файла с помощью функции execfile(). Это означает, что модули Python могут распространяться между всеми тремя операционными системами без необходимости преобразовывать окончания строк.
Эту возможность можно отключить при компиляции Python, указав флаг --without-universal-newlines при запуске скрипта configure.
См. также
- PEP 278 – Универсальная поддержка символов новой строки
- Автор и разработчик: Jack Jansen.
PEP 279: enumerate()¶
Новая встроенная функция enumerate() делает некоторые циклы немного понятнее. enumerate(thing), где thing – либо итератор, либо последовательность, возвращает итератор, который возвращает (0, thing[0]), (1, thing[1]), (2, thing[2]) и так далее.
Типичный способ изменить каждый элемент списка выглядит так:
for i in range(len(L)):
item = L[i]
# ... вычислить результат на основе элемента ...
L[i] = result
Это можно переписать с использованием enumerate() следующим образом:
for i, item in enumerate(L):
# ... вычислить результат на основе элемента ...
L[i] = result
См. также
- PEP 279 – Встроенная функция enumerate()
- Автор и разработчик: Raymond D. Hettinger.
PEP 282: Пакет logging¶PEP 282: The logging Package
В Python 2.3 добавлен стандартный пакет для ведения журналов – logging. Он предоставляет мощный и гибкий механизм для генерации записей журнала, которые затем можно фильтровать и обрабатывать различными способами. Для управления поведением журналирования программы можно использовать файл конфигурации в стандартном формате. Python включает обработчики, которые могут записывать записи журнала в стандартный поток ошибок, в файл или сокет, отправлять их в системный журнал или даже отправлять по электронной почте на определённый адрес; конечно, можно также написать собственные классы обработчиков.
Класс Logger является основным классом. Большая часть прикладного кода будет работать с одним или несколькими объектами Logger, каждый из которых используется конкретной подсистемой приложения. Каждый Logger идентифицируется именем, и имена организованы в иерархию с использованием . в качестве разделителя компонентов. Например, у вас могут быть экземпляры Logger с именами server, server.auth и server.network. Последние два экземпляра находятся ниже server в иерархии. Это означает, что если вы увеличите подробность для server или направите сообщения server другому обработчику, изменения также будут применены к записям, регистрируемым для server.auth и server.network. Существует также корневой Logger, который является родителем всех остальных регистраторов.
Для простых случаев пакет logging содержит несколько удобных функций, которые всегда используют корневой логгер:
import logging
logging.debug('Debugging information')
logging.info('Informational message')
logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shutting down')
Это даёт следующий вывод:
WARNING:root:Warning:config file server.conf not found
ERROR:root:Error occurred
CRITICAL:root:Critical error -- shutting down
В конфигурации по умолчанию информационные сообщения и сообщения отладки подавляются, а вывод направляется в стандартный поток ошибок. Можно включить отображение информационных и отладочных сообщений, вызвав метод setLevel() на корневом логгере.
Обратите внимание на использование операторов форматирования строк в вызове warning(); все функции для записи сообщений в журнал принимают аргументы (msg, arg1, arg2, ...) и записывают строку, полученную в результате msg % (arg1, arg2, ...).
Существует также функция exception(), которая записывает самую последнюю traceback. Любая из других функций также запишет traceback, если указать истинное значение для именованного аргумента exc_info.
def f():
try: 1/0
except: logging.exception('Problem recorded')
f()
Это даёт следующий вывод:
ERROR:root:Problem recorded
Traceback (most recent call last):
File "t.py", line 6, in f
1/0
ZeroDivisionError: integer division or modulo by zero
Немного более продвинутые программы используют логгер, отличный от корневого. Функция getLogger(name) используется для получения конкретного лога, создавая его, если его еще нет. getLogger(None) возвращает корневой логгер.
log = logging.getLogger('server')
...
log.info('Listening on port %i', port)
...
log.critical('Disk full')
...
Записи журнала обычно распространяются вверх по иерархии, поэтому сообщение, записанное в server.auth, также видно логгерам server и root, но Logger может предотвратить это, установив своё свойство propagate в значение False.
Пакет logging предоставляет и другие классы, которые можно настраивать. Когда экземпляру Logger поступает команда записать сообщение, он создает экземпляр LogRecord, который отправляется любому количеству различных экземпляров Handler. Логгеры и обработчики также могут иметь присоединенный список фильтров, и каждый фильтр может привести к игнорированию LogRecord или может изменить запись перед передачей. При окончательном выводе экземпляры LogRecord преобразуются в текст классом Formatter. Все эти классы могут быть заменены собственными специально написанными классами.
Со всеми этими возможностями пакет logging должен обеспечивать достаточную гибкость даже для самых сложных приложений. Это лишь неполный обзор его функций; пожалуйста, обратитесь к справочной документации пакета за всеми подробностями. Также полезно прочитать PEP 282.
См. также
- PEP 282 – Система логирования
- Написано Vinay Sajip и Trent Mick; реализовано Vinay Sajip.
PEP 285: Логический тип¶PEP 285: A Boolean Type
Логический тип был добавлен в Python 2.3. В модуль __builtin__ были добавлены две новые константы, True и False. (Константы True и False были добавлены во встроенные константы в Python 2.2.1, но версии 2.2.1 просто установлены в целочисленные значения 1 и 0 и не являются отдельным типом.)
Объект типа для этого нового типа называется bool; его конструктор принимает любое значение Python и преобразует его в True или False.
>>> bool(1)
True
>>> bool(0)
False
>>> bool([])
False
>>> bool( (1,) )
True
Большинство модулей стандартной библиотеки и встроенных функций были изменены, чтобы возвращать логические значения.
>>> obj = []
>>> hasattr(obj, 'append')
True
>>> isinstance(obj, list)
True
>>> isinstance(obj, tuple)
False
Логический тип Python был добавлен с основной целью сделать код более понятным. Например, читая функцию и встречая оператор return 1, можно задаться вопросом, представляет ли 1 логическое значение, индекс или коэффициент, умножающий другую величину. Если же оператор – return True, смысл возвращаемого значения совершенно ясен.
Логический тип Python был не добавлен ради строгой проверки типов. Очень строгий язык, такой как Pascal, также запретил бы выполнять арифметические операции с логическими значениями и потребовал бы, чтобы выражение в операторе if всегда вычислялось до логического результата. Python не настолько строг и никогда не будет, как явно указано в PEP 285. Это означает, что можно по-прежнему использовать любое выражение в операторе if, даже те, которые вычисляются в список, кортеж или какой-нибудь произвольный объект. Логический тип является подклассом класса int, так что арифметика с логическими значениями по-прежнему работает.
>>> True + 1
2
>>> False + 1
1
>>> False * 75
0
>>> True * 75
75
Если резюмировать True и False одной фразой: это альтернативные способы записи целочисленных значений 1 и 0, с единственным отличием: функции str() и repr() возвращают строки 'True' и 'False' вместо '1' и '0'.
См. также
- PEP 285 – Добавление логического типа
- Автор и разработчик: GvR.
PEP 293: Колбэки обработки ошибок кодеков¶PEP 293: Codec Error Handling Callbacks
При кодировании строки Unicode в байтовую строку могут встретиться символы, которые невозможно закодировать. До сих пор Python позволял задавать обработку ошибок как «strict» (вызывает UnicodeError), «ignore» (пропускает символ) или «replace» (использует вопросительный знак в выходной строке), при этом «strict» является поведением по умолчанию. Может потребоваться указать альтернативную обработку таких ошибок, например, вставку ссылки на символ XML или ссылки на сущность HTML в преобразованную строку.
В Python теперь есть гибкая инфраструктура для добавления различных стратегий обработки. Новые обработчики ошибок можно добавить с помощью codecs.register_error(), после чего кодек может получить доступ к обработчику ошибок с помощью codecs.lookup_error(). Для кодеков, написанных на C, был добавлен эквивалентный C API. Обработчик ошибок получает необходимую информацию о состоянии, такую как преобразуемая строка, позиция в строке, где была обнаружена ошибка, и целевая кодировка. Затем обработчик может либо вызвать исключение, либо вернуть строку замены.
С помощью этой платформы были реализованы два дополнительных обработчика ошибок: «backslashreplace» использует экранирование обратной косой чертой Python для представления незакодируемых символов, а «xmlcharrefreplace» генерирует ссылки на символы XML.
См. также
- PEP 293 – Колбэки обработки ошибок кодеков
- Автор и разработчик: Walter Dörwald.
PEP 301: Индекс пакетов и метаданные для Distutils¶PEP 301: Package Index and Metadata for Distutils
Поддержка долгожданного каталога Python впервые появляется в версии 2.3.
Основой каталога является новая команда Distutils register. Выполнение python setup.py register собирает метаданные пакета: имя, версию, автора, описание и т. д. – и отправляет их на центральный сервер каталога. Полученный каталог доступен по адресу http://www.python.org/pypi.
Чтобы сделать каталог немного более полезным, в функцию setup() Distutils был добавлен новый необязательный именованный аргумент classifiers. Можно указать список строк в стиле Trove, чтобы помочь классифицировать программное обеспечение.
Вот пример setup.py с классификаторами, написанный для совместимости со старыми версиями Distutils:
from distutils import core
kw = {'name': "Quixote",
'version': "0.5.1",
'description': "A highly Pythonic Web application framework",
# ...
}
if (hasattr(core, 'setup_keywords') and
'classifiers' in core.setup_keywords):
kw['classifiers'] = \
['Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Environment :: No Input/Output (Daemon)',
'Intended Audience :: Developers'],
core.setup(**kw)
Полный список классификаторов можно получить, выполнив python setup.py register --list-classifiers.
См. также
- PEP 301 – Индекс пакетов и метаданные для Distutils
- Автор и разработчик: Richard Jones.
PEP 302: Новые хуки импорта¶PEP 302: New Import Hooks
Хотя возможность писать пользовательские хуки импорта существовала с момента появления модуля ihooks в Python 1.3, никто не был по-настоящему доволен этим, потому что написание новых хуков импорта – дело сложное и запутанное. Были предложены различные альтернативы, такие как модули imputil и iu, но ни одна из них не получила широкого признания, и ни одна из них не была легко используемой из кода на C.
PEP 302 заимствует идеи у своих предшественников, особенно у модуля Гордона Макмиллана iu. В модуль sys добавлены три новых элемента:
- sys.path_hooks – это список вызываемых объектов; чаще всего это будут классы. Каждый вызываемый объект принимает строку, содержащую путь, и либо возвращает объект импортера, который будет обрабатывать импорт из этого пути, либо вызывает исключение ImportError, если не может обработать этот путь.
- sys.path_importer_cache кеширует объекты импортеров для каждого пути, так что sys.path_hooks нужно будет проходить только один раз для каждого пути.
- sys.meta_path – это список объектов импортеров, которые будут просматриваться до того, как будет проверен sys.path. Этот список изначально пуст, но пользовательский код может добавлять в него объекты. Дополнительные встроенные и замороженные модули могут быть импортированы объектом, добавленным в этот список.
Объекты импортеров должны иметь единственный метод: find_module(fullname, path=None). fullname будет именем модуля или пакета, например, string или distutils.core. find_module() должен возвращать объект загрузчика, который имеет единственный метод, load_module(fullname), который создает и возвращает соответствующий объект модуля.
Псевдокод новой логики импорта в Python выглядит примерно так (немного упрощён; полные подробности см. в PEP 302):
for mp in sys.meta_path:
loader = mp(fullname)
if loader is not None:
<module> = loader.load_module(fullname)
for path in sys.path:
for hook in sys.path_hooks:
try:
importer = hook(path)
except ImportError:
# ImportError, поэтому попробуем другие перехватчики путей
pass
else:
loader = importer.find_module(fullname)
<module> = loader.load_module(fullname)
# Не найдено!
raise ImportError
См. также
- PEP 302 – новые хуки импорта
- Автор: Just van Rossum и Paul Moore. Реализовано Just van Rossum.
PEP 305: Файлы с разделителями-запятыми¶PEP 305: Comma-separated Files
Файлы с разделителями-запятыми – это формат, часто используемый для экспорта данных из баз данных и электронных таблиц. В Python 2.3 добавлен синтаксический анализатор таких файлов.
Формат с разделителями-запятыми на первый взгляд обманчиво прост:
Costs,150,200,3.95
Прочитать строку и вызвать line.split(','): что может быть проще? Но добавьте строковые данные, которые могут содержать запятые, и всё становится сложнее:
"Costs",150,200,3.95,"Includes taxes, shipping, and sundry items"
Большое уродливое регулярное выражение может это разобрать, но использование нового пакета csv гораздо проще:
import csv
input = open('datafile', 'rb')
reader = csv.reader(input)
for line in reader:
print line
Функция reader() принимает множество различных параметров. Разделитель полей не ограничен запятой и может быть изменен на любой символ, как и символы кавычек и окончания строки.
Можно определять и регистрировать различные диалекты файлов с разделителями-запятыми; в настоящее время есть два диалекта, оба используются Microsoft Excel. Отдельный класс csv.writer будет генерировать файлы с разделителями-запятыми из последовательности кортежей или списков, заключая в кавычки строки, содержащие разделитель.
См. также
- PEP 305 - API для CSV-файлов
- Авторы и разработчики: Kevin Altis, Dave Cole, Andrew McNamara, Skip Montanaro, Cliff Wells.
PEP 307: Улучшения pickle¶PEP 307: Pickle Enhancements
Модули pickle и cPickle привлекли некоторое внимание в ходе цикла разработки 2.3. В версии 2.2 классы нового стиля можно было без труда сериализовать с помощью pickle, но они сериализовались не очень компактно; PEP 307 приводит тривиальный пример, где класс нового стиля приводит к строке pickle в три раза длиннее, чем для классического класса.
Решением стало изобретение нового протокола pickle. Функция pickle.dumps() уже давно поддерживает флаг текст/бинар. В версии 2.3 этот флаг переопределен с логического на целочисленный: 0 – старый текстовый формат pickle, 1 – старый бинарный формат, а теперь 2 – новый формат, специфичный для 2.3. Новая константа, pickle.HIGHEST_PROTOCOL, может использоваться для выбора самого навороченного доступного протокола.
Десериализация pickle больше не считается безопасной операцией. В Python 2.2 модуль pickle предоставлял хуки для попытки предотвратить десериализацию небезопасных классов (а именно атрибут __safe_for_unpickling__), но этот код никогда не был проверен аудитом, и поэтому в 2.3 он был целиком удален. Не следует десериализовать недоверенные данные в любой версии Python.
To reduce the pickling overhead for new-style classes, a new interface for customizing pickling was added using three special methods: __getstate__(), __setstate__(), and __getnewargs__(). Consult PEP 307 for the full semantics of these methods.
Для ещё большего сжатия pickle теперь можно использовать целочисленные коды вместо длинных строк для идентификации сериализованных классов. Python Software Foundation будет поддерживать список стандартизированных кодов; также существует диапазон кодов, зарезервированных для частного использования. В настоящее время коды не определены.
См. также
- PEP 307 – расширения протокола pickle
- Авторы и разработчики: Guido van Rossum и Tim Peters.
Расширенные срезы¶Extended Slices
Ever since Python 1.4, the slicing syntax has supported an optional third “step” or “stride” argument. For example, these are all legal Python syntax: L[1:10:2], L[:-1:1], L[::-1]. This was added to Python at the request of the developers of Numerical Python, which uses the third argument extensively. However, Python’s built-in list, tuple, and string sequence types have never supported this feature, raising a TypeError if you tried it. Michael Hudson contributed a patch to fix this shortcoming.
Например, теперь можно легко извлечь элементы списка с чётными индексами:
>>> L = range(10)
>>> L[::2]
[0, 2, 4, 6, 8]
Отрицательные значения также работают, чтобы создать копию того же списка в обратном порядке:
>>> L[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Это также работает для кортежей, массивов и строк:
>>> s='abcd'
>>> s[::2]
'ac'
>>> s[::-1]
'dcba'
Если у вас есть изменяемая последовательность, например список или массив, вы можете присваивать значение расширенному срезу или удалять его, но есть некоторые различия между присваиванием расширенным и обычным срезам. Присваивание обычному срезу может использоваться для изменения длины последовательности:
>>> a = range(3)
>>> a
[0, 1, 2]
>>> a[1:3] = [4, 5, 6]
>>> a
[0, 4, 5, 6]
Расширенные срезы не настолько гибки. При присваивании расширенному срезу список в правой части оператора должен содержать то же количество элементов, что и заменяемый срез:
>>> a = range(4)
>>> a
[0, 1, 2, 3]
>>> a[::2]
[0, 2]
>>> a[::2] = [0, -1]
>>> a
[0, 1, -1, 3]
>>> a[::2] = [0,1,2]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: attempt to assign sequence of size 3 to extended slice of size 2
Удаление выполняется проще:
>>> a = range(4)
>>> a
[0, 1, 2, 3]
>>> a[::2]
[0, 2]
>>> del a[::2]
>>> a
[1, 3]
One can also now pass slice objects to the __getitem__() methods of the built-in sequences:
>>> range(10).__getitem__(slice(0, 5, 2))
[0, 2, 4]
Или использовать объекты срезов непосредственно в индексации:
>>> range(10)[slice(0, 5, 2)]
[0, 2, 4]
To simplify implementing sequences that support extended slicing, slice objects now have a method indices(length) which, given the length of a sequence, returns a (start, stop, step) tuple that can be passed directly to range(). indices() handles omitted and out-of-bounds indices in a manner consistent with regular slices (and this innocuous phrase hides a welter of confusing details!). The method is intended to be used like this:
class FakeSeq:
...
def calc_item(self, i):
...
def __getitem__(self, item):
if isinstance(item, slice):
indices = item.indices(len(self))
return FakeSeq([self.calc_item(i) for i in range(*indices)])
else:
return self.calc_item(i)
From this example you can also see that the built-in slice object is now the type object for the slice type, and is no longer a function. This is consistent with Python 2.2, where int, str, etc., underwent the same change.
Прочие изменения языка ¶Other Language Changes
Ниже перечислены все изменения, которые Python 2.3 вносит в ядро языка Python.
The yield statement is now always a keyword, as described in section PEP 255: Simple Generators of this document.
A new built-in function enumerate() was added, as described in section PEP 279: enumerate() of this document.
Two new constants, True and False were added along with the built-in bool type, as described in section PEP 285: A Boolean Type of this document.
The int() type constructor will now return a long integer instead of raising an OverflowError when a string or floating-point number is too large to fit into an integer. This can lead to the paradoxical result that isinstance(int(expression), int) is false, but that seems unlikely to cause problems in practice.
Встроенные типы теперь поддерживают расширенный синтаксис срезов, как описано в разделе Extended Slices этого документа.
A new built-in function, sum(iterable, start=0), adds up the numeric items in the iterable object and returns their sum. sum() only accepts numbers, meaning that you can’t use it to concatenate a bunch of strings. (Contributed by Alex Martelli.)
list.insert(pos, value) used to insert value at the front of the list when pos was negative. The behaviour has now been changed to be consistent with slice indexing, so when pos is -1 the value will be inserted before the last element, and so forth.
list.index(value), which searches for value within the list and returns its index, now takes optional start and stop arguments to limit the search to only part of the list.
Dictionaries have a new method, pop(key[, *default*]), that returns the value corresponding to key and removes that key/value pair from the dictionary. If the requested key isn’t present in the dictionary, default is returned if it’s specified and KeyError raised if it isn’t.
>>> d = {1:2} >>> d {1: 2} >>> d.pop(4) Traceback (most recent call last): File "stdin", line 1, in ? KeyError: 4 >>> d.pop(1) 2 >>> d.pop(1) Traceback (most recent call last): File "stdin", line 1, in ? KeyError: 'pop(): dictionary is empty' >>> d {} >>>
There’s also a new class method, dict.fromkeys(iterable, value), that creates a dictionary with keys taken from the supplied iterator iterable and all values set to value, defaulting to None.
(Патчи предоставлены Raymond Hettinger.)
Also, the dict() constructor now accepts keyword arguments to simplify creating small dictionaries:
>>> dict(red=1, blue=2, green=3, black=4) {'blue': 2, 'black': 4, 'green': 3, 'red': 1}
(Автор: Just van Rossum.)
The assert statement no longer checks the __debug__ flag, so you can no longer disable assertions by assigning to __debug__. Running Python with the -O switch will still generate code that doesn’t execute any assertions.
Most type objects are now callable, so you can use them to create new objects such as functions, classes, and modules. (This means that the new module can be deprecated in a future Python version, because you can now use the type objects available in the types module.) For example, you can create a new module object with the following code:
>>> import types >>> m = types.ModuleType('abc','docstring') >>> m <module 'abc' (built-in)> >>> m.__doc__ 'docstring'
A new warning, PendingDeprecationWarning was added to indicate features which are in the process of being deprecated. The warning will not be printed by default. To check for use of features that will be deprecated in the future, supply -Walways::PendingDeprecationWarning:: on the command line or use warnings.filterwarnings().
The process of deprecating string-based exceptions, as in raise "Error occurred", has begun. Raising a string will now trigger PendingDeprecationWarning.
Using None as a variable name will now result in a SyntaxWarning warning. In a future version of Python, None may finally become a keyword.
The xreadlines() method of file objects, introduced in Python 2.1, is no longer necessary because files now behave as their own iterator. xreadlines() was originally introduced as a faster way to loop over all the lines in a file, but now you can simply write for line in file_obj. File objects also have a new read-only encoding attribute that gives the encoding used by the file; Unicode strings written to the file will be automatically converted to bytes using the given encoding.
Порядок разрешения методов, используемый классами нового стиля, изменился, хотя разницу вы заметите только при действительно сложной иерархии наследования. Классические классы это изменение не затрагивает. В Python 2.2 изначально использовалась топологическая сортировка предков класса, но в 2.3 теперь применяется алгоритм C3, описанный в статье «A Monotonic Superclass Linearization for Dylan». Чтобы понять мотивацию этого изменения, прочтите статью Микеле Симониато «Python 2.3 Method Resolution Order» или обсуждение в списке рассылки python-dev, начиная с сообщения по адресу http://mail.python.org/pipermail/python-dev/2002-October/029035.html. Самуэле Педрони первым указал на проблему и реализовал исправление, написав алгоритм C3.
Python runs multithreaded programs by switching between threads after executing N bytecodes. The default value for N has been increased from 10 to 100 bytecodes, speeding up single-threaded applications by reducing the switching overhead. Some multithreaded applications may suffer slower response time, but that’s easily fixed by setting the limit back to a lower number using sys.setcheckinterval(N). The limit can be retrieved with the new sys.getcheckinterval() function.
One minor but far-reaching change is that the names of extension types defined by the modules included with Python now contain the module and a '.' in front of the type name. For example, in Python 2.2, if you created a socket and printed its __class__, you’d get this output:
>>> s = socket.socket() >>> s.__class__ <type 'socket'>
В 2.3 вы получите это:
>>> s.__class__ <type '_socket.socket'>
Одна из известных несовместимостей между классами старого и нового стиля устранена: теперь можно присваивать значения атрибутам __name__ и __bases__ классов нового стиля. Существуют некоторые ограничения на то, что можно присваивать __bases__, аналогичные ограничениям на присваивание атрибуту __class__ экземпляра.
Изменения строк¶String Changes
The in operator now works differently for strings. Previously, when evaluating X in Y where X and Y are strings, X could only be a single character. That’s now changed; X can be a string of any length, and X in Y will return True if X is a substring of Y. If X is the empty string, the result is always True.
>>> 'ab' in 'abcd' True >>> 'ad' in 'abcd' False >>> '' in 'abcd' True
Note that this doesn’t tell you where the substring starts; if you need that information, use the find() string method.
The strip(), lstrip(), and rstrip() string methods now have an optional argument for specifying the characters to strip. The default is still to remove all whitespace characters:
>>> ' abc '.strip() 'abc' >>> '><><abc<><><>'.strip('<>') 'abc' >>> '><><abc<><><>\n'.strip('<>') 'abc<><><>\n' >>> u'\u4000\u4001abc\u4000'.strip(u'\u4000') u'\u4001abc' >>>
(Предложено Simon Brunning и реализовано Walter Dörwald.)
The startswith() and endswith() string methods now accept negative numbers for the start and end parameters.
Another new string method is zfill(), originally a function in the string module. zfill() pads a numeric string with zeros on the left until it’s the specified width. Note that the % operator is still more flexible and powerful than zfill().
>>> '45'.zfill(4) '0045' >>> '12345'.zfill(4) '12345' >>> 'goofy'.zfill(6) '0goofy'
(Автор: Walter Dörwald.)
A new type object, basestring, has been added. Both 8-bit strings and Unicode strings inherit from this type, so isinstance(obj, basestring) will return True for either kind of string. It’s a completely abstract type, so you can’t create basestring instances.
Интернированные строки больше не бессмертны и теперь собираются сборщиком мусора обычным образом, когда единственная ссылка на них – из внутреннего словаря интернированных строк. (Реализовано Oren Tirosh.)
Оптимизации¶Optimizations
- Создание экземпляров классов нового стиля стало намного быстрее; теперь они быстрее, чем экземпляры классических классов!
- The sort() method of list objects has been extensively rewritten by Tim Peters, and the implementation is significantly faster.
- Умножение больших целых чисел теперь выполняется гораздо быстрее благодаря реализации умножения Карацубы – алгоритма, масштабируемость которого лучше, чем O(n*n), необходимого для алгоритма умножения из начальной школы. (Оригинальный патч от Кристофера А. Крейга, значительно переработан Тимом Питерсом.)
- The SET_LINENO opcode is now gone. This may provide a small speed increase, depending on your compiler’s idiosyncrasies. See section Other Changes and Fixes for a longer explanation. (Removed by Michael Hudson.)
- Объекты xrange() теперь имеют собственный итератор, что делает for i in xrange(n) немного быстрее, чем for i in range(n). (Патч от Рэймонда Хеттингера.)
- Был выполнен ряд небольших перестановок в различных горячих точках для повышения производительности, например, встраивание функции или удаление некоторого кода. (В основном реализовано GvR, но многие люди внесли отдельные изменения.)
Итоговый результат оптимизаций в версии 2.3: Python 2.3 выполняет тест pystone примерно на 25% быстрее, чем Python 2.2.
Новые, улучшенные и устаревшие модули¶New, Improved, and Deprecated Modules
Как обычно, стандартная библиотека Python получила ряд улучшений и исправлений ошибок. Вот частичный список наиболее заметных изменений, отсортированный по модулям в алфавитном порядке. За полным списком изменений обращайтесь к файлу Misc/NEWS в дереве исходных текстов, или просмотрите журналы CVS для получения всех подробностей.
Модуль array теперь поддерживает массивы символов Unicode с использованием символа формата 'u'. Массивы также теперь поддерживают оператор присваивания += для добавления содержимого другого массива, и оператор присваивания *= для повторения массива. (Предложено Джейсоном Орендорффом.)
Модуль bsddb заменен версией 4.1.6 пакета PyBSDDB, предоставляющего более полный интерфейс к транзакционным возможностям библиотеки BerkeleyDB.
Старая версия модуля переименована в bsddb185 и больше не собирается автоматически; вам придется отредактировать Modules/Setup, чтобы включить её. Обратите внимание, что новый пакет bsddb предполагается совместимым со старым модулем, так что обязательно сообщайте об ошибках, если обнаружите несовместимости. При обновлении до Python 2.3, если новый интерпретатор скомпилирован с новой версией библиотеки BerkeleyDB, вам почти наверняка придется конвертировать файлы базы данных в новую версию. Это можно довольно легко сделать с помощью новых скриптов db2pickle.py и pickle2db.py, которые находятся в каталоге Tools/scripts дистрибутива. Если вы уже использовали пакет PyBSDDB и импортировали его как bsddb3, вам придется изменить операторы import, чтобы импортировать его как bsddb.
Новый модуль bz2 – это интерфейс к библиотеке сжатия данных bz2. Данные, сжатые bz2, обычно меньше соответствующих данных, сжатых zlib. (Предложено Густаво Нимейером.)
В новом модуле datetime добавлен набор стандартных типов даты/времени. Подробнее см. следующий раздел.
Класс Extension из Distutils теперь поддерживает дополнительный аргумент конструктора с именем depends для перечисления дополнительных исходных файлов, от которых зависит расширение. Это позволяет Distutils перекомпилировать модуль при изменении любого из файлов зависимостей. Например, если sampmodule.c включает заголовочный файл sample.h, вы создадите объект Extension так:
ext = Extension("samp", sources=["sampmodule.c"], depends=["sample.h"])
Изменение sample.h приведет к перекомпиляции модуля. (Предложено Джереми Хилтоном.)
Другие мелкие изменения в Distutils: теперь он проверяет переменные окружения CC, CFLAGS, CPP, LDFLAGS и CPPFLAGS, используя их для переопределения настроек конфигурации Python (предложено Робертом Вебером).
Ранее модуль doctest искал тестовые примеры только в документирующих строках публичных методов и функций, но теперь он также проверяет и приватные. Функция DocTestSuite() создает объект unittest.TestSuite из набора тестов doctest.
Новая функция gc.get_referents(object) возвращает список всех объектов, на которые ссылается object.
Модуль getopt получил новую функцию gnu_getopt(), которая поддерживает те же аргументы, что и существующая функция getopt(), но использует режим сканирования в стиле GNU. Существующая getopt() прекращает обработку опций, как только встречает неопционный аргумент, но в режиме GNU обработка продолжается, то есть опции и аргументы могут смешиваться. Например:
>>> getopt.getopt(['-f', 'filename', 'output', '-v'], 'f:v') ([('-f', 'filename')], ['output', '-v']) >>> getopt.gnu_getopt(['-f', 'filename', 'output', '-v'], 'f:v') ([('-f', 'filename'), ('-v', '')], ['output'])
(Автор: Peter Åstrand.)
Модули grp, pwd и resource теперь возвращают расширенные кортежи:
>>> import grp >>> g = grp.getgrnam('amk') >>> g.gr_name, g.gr_gid ('amk', 500)
Модуль gzip теперь может обрабатывать файлы размером более 2 ГБ.
Новый модуль heapq содержит реализацию алгоритма пирамидальной очереди (кучи). Куча – это структура данных, похожая на массив, которая хранит элементы в частично отсортированном порядке, так что для каждого индекса k выполняется heap[k] <= heap[2*k+1] и heap[k] <= heap[2*k+2]. Это позволяет быстро удалять наименьший элемент, а вставка нового элемента с сохранением свойства кучи выполняется за O(lg n). (Дополнительную информацию о структуре данных «очередь с приоритетом» см. на http://www.nist.gov/dads/HTML/priorityque.html.)
Модуль heapq предоставляет функции heappush() и heappop() для добавления и удаления элементов с сохранением свойства кучи поверх некоторого другого изменяемого типа последовательности Python. Вот пример с использованием списка Python:
>>> import heapq >>> heap = [] >>> for item in [3, 7, 5, 11, 1]: ... heapq.heappush(heap, item) ... >>> heap [1, 3, 5, 11, 7] >>> heapq.heappop(heap) 1 >>> heapq.heappop(heap) 3 >>> heap [5, 7, 11]
(Автор: Kevin O’Connor.)
Интегрированная среда разработки IDLE обновлена с использованием кода из проекта IDLEfork (http://idlefork.sf.net). Наиболее примечательная особенность: разрабатываемый код теперь выполняется в подпроцессе, что устраняет необходимость в ручных вызовах reload(). Основной код IDLE включён в стандартную библиотеку в виде пакета idlelib.
Модуль imaplib теперь поддерживает IMAP через SSL. (Предложено Пирсом Лаудером и Тино Ланге.)
Модуль itertools содержит ряд полезных функций для работы с итераторами, вдохновленных различными функциями из языков ML и Haskell. Например, itertools.ifilter(predicate, iterator) возвращает все элементы итератора, для которых функция predicate() возвращает True, а itertools.repeat(obj, N) возвращает obj N раз. В модуле есть и другие функции; подробности см. в справочной документации пакета. (Предложено Рэймондом Хеттингером.)
Две новые функции в модуле math, degrees(rads) и radians(degs), выполняют преобразование между радианами и градусами. Другие функции модуля math, такие как math.sin() и math.cos(), всегда требовали входные значения в радианах. Кроме того, к math.log() добавлен необязательный аргумент base, упрощающий вычисление логарифмов по основаниям, отличным от e и 10. (Предложено Рэймондом Хеттингером.)
В модуль posix, лежащий в основе модуля os, добавлено несколько новых функций POSIX: getpgid(), killpg(), lchown(), loadavg(), major(), makedev(), minor() и mknod(). (Предложено Густаво Нимейером, Гертом Янсеном и Денисом С. Откидачем.)
В модуле os семейство функций *stat() теперь может сообщать доли секунды во временной метке. Такие временные метки представляются числами с плавающей запятой, аналогично значению, возвращаемому time.time().
В ходе тестирования было обнаружено, что некоторые приложения сломаются, если временные метки будут числами с плавающей запятой. Для совместимости при использовании кортежного интерфейса stat_result временные метки будут представляться целыми числами. При использовании именованных полей (функция, впервые появившаяся в Python 2.2) временные метки по-прежнему представляются целыми числами, если только не вызвать os.stat_float_times() для включения возврата чисел с плавающей запятой:
>>> os.stat("/tmp").st_mtime 1034791200 >>> os.stat_float_times(True) >>> os.stat("/tmp").st_mtime 1034791200.6335014
В Python 2.4 значение по умолчанию изменится – всегда будут возвращаться числа с плавающей точкой.
Разработчикам приложений следует включать эту возможность только в том случае, если все их библиотеки корректно работают с метками времени с плавающей точкой, или если они используют API кортежей. При использовании эту возможность следует активировать на уровне приложения, а не пытаться включать её для каждого отдельного вызова.
Модуль optparse содержит новый анализатор аргументов командной строки, который может преобразовывать значения опций в определенный тип Python и автоматически генерировать сообщение об использовании. Подробнее см. следующий раздел.
Старый и никогда не документированный модуль linuxaudiodev объявлен устаревшим, и добавлена новая версия ossaudiodev. Модуль переименован, поскольку звуковые драйверы OSS могут использоваться на платформах, отличных от Linux, а интерфейс также был приведен в порядок и обновлен различными способами. (Предложено Грегом Уордом и Николасом ФитцРой-Дейлом.)
Новый модуль platform содержит ряд функций, которые пытаются определить различные свойства платформы, на которой вы работаете. Есть функции для получения архитектуры, типа процессора, версии ОС Windows и даже версии дистрибутива Linux. (Предложено Марком-Андре Лембургом.)
Объекты синтаксического анализатора, предоставляемые модулем pyexpat, теперь могут опционально буферизировать символьные данные, что приводит к меньшему количеству вызовов обработчика символьных данных и, следовательно, к более высокой производительности. Установка атрибута buffer_text объекта анализатора в True включит буферизацию.
Функция sample(population, k) добавлена в модуль random. population – это последовательность или объект xrange, содержащий элементы совокупности, а sample() выбирает k элементов из совокупности без повторений. k может быть любым значением вплоть до len(population). Например:
>>> days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'St', 'Sn'] >>> random.sample(days, 3) # Выбрать 3 элемента ['St', 'Sn', 'Th'] >>> random.sample(days, 7) # Выбрать 7 элементов ['Tu', 'Th', 'Mo', 'We', 'St', 'Fr', 'Sn'] >>> random.sample(days, 7) # Выбрать 7 снова ['We', 'Mo', 'Sn', 'Fr', 'Tu', 'St', 'Th'] >>> random.sample(days, 8) # Нельзя выбрать восемь Traceback (most recent call last): File "<stdin>", line 1, in ? File "random.py", line 414, in sample raise ValueError, "sample larger than population" ValueError: sample larger than population >>> random.sample(xrange(1,10000,2), 10) # Выбрать десять нечётных чисел меньше 10000 [3407, 3805, 1505, 7023, 2401, 2267, 9733, 3151, 8083, 9195]
Модуль random теперь использует новый алгоритм – вихрь Мерсенна, реализованный на C. Он быстрее и более изучен, чем предыдущий алгоритм.
(Все изменения выполнены Raymond Hettinger.)
Модуль readline также получил ряд новых функций: get_history_item(), get_current_history_length() и redisplay().
Модули rexec и Bastion объявлены мёртвыми, и попытки их импорта завершатся ошибкой RuntimeError. Классы нового стиля предоставляют новые способы выхода из ограниченной среды выполнения, предоставляемой rexec, и никто не заинтересован в их исправлении или не имеет времени на это. Если у вас есть приложения, использующие rexec, перепишите их для использования чего-то другого.
(Использование Python 2.2 или 2.1 не сделает приложения безопаснее, поскольку в этих версиях есть известные ошибки в модуле rexec. Повторюсь: если используется rexec, следует немедленно прекратить его использование.)
Модуль rotor устарел, поскольку используемый в нём алгоритм шифрования не считается безопасным. Если требуется шифрование, воспользуйтесь одним из нескольких модулей AES для Python, доступных отдельно.
В модуле shutil появилась функция move(src, dest), которая рекурсивно перемещает файл или каталог в новое расположение.
В модуль signal была добавлена поддержка более продвинутой обработки сигналов POSIX, однако позже она была удалена, поскольку обеспечить её надёжную работу на разных платформах не удалось.
Модуль socket теперь поддерживает тайм-ауты. Можно вызвать метод settimeout(t) объекта сокета, чтобы установить тайм-аут в t секунд. Последующие операции с сокетом, выполняющиеся дольше t секунд, будут прерваны с возбуждением исключения socket.timeout.
Исходная реализация тайм-аута была создана Тимом О'Мэлли. Майкл Гилфикс интегрировал её в модуль socket Python и провёл её через длительное рецензирование. После того как код был принят, Гвидо ван Россум переписал его части. (Это хороший пример совместного процесса разработки в действии.)
В Windows модуль socket теперь поставляется с поддержкой Secure Sockets Layer (SSL).
Значение макроса C PYTHON_API_VERSION теперь доступно на уровне Python как sys.api_version. Текущее исключение можно очистить, вызвав новую функцию sys.exc_clear().
Новый модуль tarfile позволяет читать и записывать архивные файлы в формате tar. (Автор: Lars Gustäbel.)
Новый модуль textwrap содержит функции для переноса строк, содержащих абзацы текста. Функция wrap(text, width) принимает строку и возвращает список, содержащий текст, разбитый на строки не длиннее заданной ширины. Функция fill(text, width) возвращает одну строку, переформатированную так, чтобы она помещалась в строки не длиннее заданной ширины. (Как можно догадаться, fill() построена на основе wrap(). Например:
>>> import textwrap >>> paragraph = "Not a whit, we defy augury: ... more text ..." >>> textwrap.wrap(paragraph, 60) ["Not a whit, we defy augury: there's a special providence in", "the fall of a sparrow. If it be now, 'tis not to come; if it", ...] >>> print textwrap.fill(paragraph, 35) Not a whit, we defy augury: there's a special providence in the fall of a sparrow. If it be now, 'tis not to come; if it be not to come, it will be now; if it be not now, yet it will come: the readiness is all. >>>
Модуль также содержит класс TextWrapper, который фактически реализует стратегию переноса текста. Как класс TextWrapper, так и функции wrap() и fill() поддерживают ряд дополнительных именованных аргументов для точной настройки форматирования; подробности см. в документации модуля. (Автор: Greg Ward.)
Модули thread и threading теперь имеют вспомогательные модули dummy_thread и dummy_threading, которые предоставляют фиктивную реализацию интерфейса модуля thread для платформ, не поддерживающих потоки. Цель – упростить модули, учитывающие наличие потоков (те, которые не полагаются на потоки для своей работы), разместив в начале следующий код:
try: import threading as _threading except ImportError: import dummy_threading as _threading
В этом примере _threading используется в качестве имени модуля, чтобы подчеркнуть, что используемый модуль не обязательно является настоящим модулем threading. Код может вызывать функции и использовать классы из _threading независимо от того, поддерживаются ли потоки, что позволяет избежать инструкции if и делает код немного понятнее. Этот модуль не заставит магическим образом многопоточный код работать без потоков; код, ожидающий возврата или выполнения другого потока, просто зависнет навсегда.
Функция strptime() модуля time долгое время вызывала неудобства, поскольку использовала реализацию strptime() из библиотеки C платформы, а на разных платформах иногда встречались странные ошибки. Бретт Кэннон предоставил переносимую реализацию, написанную на чистом Python, которая должна вести себя одинаково на всех платформах.
Новый модуль timeit помогает измерять время выполнения фрагментов кода Python. Файл timeit.py можно запускать непосредственно из командной строки, или же можно импортировать и использовать класс Timer модуля. Вот короткий пример, определяющий, что быстрее: преобразовать 8-битную строку в Unicode путём добавления пустой строки Unicode или с помощью функции unicode():
import timeit timer1 = timeit.Timer('unicode("abc")') timer2 = timeit.Timer('"abc" + u""') # Провести три испытания print timer1.repeat(repeat=3, number=100000) print timer2.repeat(repeat=3, number=100000) # На моём ноутбуке это выводит: # [0.36831796169281006, 0.37441694736480713, 0.35304892063140869] # [0.17574405670166016, 0.18193507194519043, 0.17565798759460449]
Модуль Tix получил различные исправления ошибок и обновления для текущей версии пакета Tix.
Модуль Tkinter теперь работает с версией Tcl, поддерживающей потоки. Модель потоков Tcl требует, чтобы виджеты были доступны только из того потока, в котором они созданы; доступ из другого потока может привести к панике Tcl. Для определённых интерфейсов Tcl Tkinter теперь автоматически избегает этого при доступе к виджету из другого потока, упаковывая команду, передавая её в правильный поток и ожидая результатов. Другие интерфейсы не могут обрабатываться автоматически, но Tkinter теперь будет вызывать исключение при таком доступе, чтобы вы хотя бы могли узнать о проблеме. См. http://mail.python.org/pipermail/python-dev/2002-December/031107.html для более подробного объяснения этого изменения. (Реализовано Мартином фон Лёвисом.)
Вызов методов Tcl через _tkinter теперь возвращает не только строки. Если Tcl возвращает другие объекты, они преобразуются в эквивалент Python, если таковой существует, или оборачиваются в объект _tkinter.Tcl_Obj, если эквивалента нет. Этим поведением можно управлять через метод wantobjects() объектов tkapp.
При использовании _tkinter через модуль Tkinter (как и делают большинство приложений Tkinter) эта возможность всегда включена. Это не должно вызывать проблем совместимости, поскольку Tkinter всегда по возможности преобразует строковые результаты в типы Python.
Если будут обнаружены несовместимости, можно восстановить старое поведение, установив переменную wantobjects в модуле Tkinter в значение false перед созданием первого объекта tkapp.
import Tkinter Tkinter.wantobjects = 0
Любые проблемы, вызванные этим изменением, следует сообщать как об ошибке.
В модуле UserDict появился новый класс DictMixin, который определяет все методы словаря для классов, уже имеющих минимальный интерфейс отображения. Это значительно упрощает написание классов, которые должны быть взаимозаменяемы со словарями, например классов в модуле shelve.
Добавление примеси в качестве суперкласса предоставляет полный интерфейс словаря, если класс определяет __getitem__(), __setitem__(), __delitem__() и keys(). Например:
>>> import UserDict >>> class SeqDict(UserDict.DictMixin): ... """Подобие словаря, реализованное с помощью списков.""" ... def __init__(self): ... self.keylist = [] ... self.valuelist = [] ... def __getitem__(self, key): ... try: ... i = self.keylist.index(key) ... except ValueError: ... raise KeyError ... return self.valuelist[i] ... def __setitem__(self, key, value): ... try: ... i = self.keylist.index(key) ... self.valuelist[i] = value ... except ValueError: ... self.keylist.append(key) ... self.valuelist.append(value) ... def __delitem__(self, key): ... try: ... i = self.keylist.index(key) ... except ValueError: ... raise KeyError ... self.keylist.pop(i) ... self.valuelist.pop(i) ... def keys(self): ... return list(self.keylist) ... >>> s = SeqDict() >>> dir(s) # Посмотреть, что другие методы словаря реализованы ['__cmp__', '__contains__', '__delitem__', '__doc__', '__getitem__', '__init__', '__iter__', '__len__', '__module__', '__repr__', '__setitem__', 'clear', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keylist', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'valuelist', 'values']
(Автор: Raymond Hettinger.)
Реализация DOM в модуле xml.dom.minidom теперь может генерировать вывод XML в определённой кодировке, если передать необязательный аргумент encoding методам toxml() и toprettyxml() узлов DOM.
Модуль xmlrpclib теперь поддерживает расширение XML-RPC для обработки нулевых значений данных, таких как None в Python. Нулевые значения всегда поддерживаются при демаршалинге ответа XML-RPC. Чтобы сгенерировать запросы, содержащие None, необходимо передать истинное значение для параметра allow_none при создании экземпляра Marshaller.
Новый модуль DocXMLRPCServer позволяет писать самодокументируемые XML-RPC серверы. Запустите его в демонстрационном режиме (как программу), чтобы увидеть его в действии. Если направить веб-браузер на RPC-сервер, будет показана документация в стиле pydoc; если направить xmlrpclib на сервер, можно вызывать реальные методы. (Автор: Brian Quinlan.)
Добавлена поддержка интернационализированных доменных имен (RFC 3454, 3490, 3491, 3492). Кодировка "idna" может использоваться для преобразования между доменным именем в Unicode и его ASCII-совместимой кодировкой (ACE).
>{}>{}> u"www.Alliancefrançaise.nu".encode("idna") 'www.xn--alliancefranaise-npb.nu'
Модуль socket также был расширен для прозрачного преобразования Unicode-имён хостов в версию ACE перед передачей их библиотеке C. Модули, работающие с именами хостов, такие как httplib и ftplib), также поддерживают Unicode-имена хостов; httplib также отправляет HTTP-заголовки Host, используя ACE-версию доменного имени. urllib поддерживает URL в Unicode с не-ASCII именами хостов, если часть URL path содержит только ASCII.
Для реализации этого изменения были добавлены модуль stringprep, инструмент mkstringprep и кодировка punycode.
Типы даты/времени¶Date/Time Type
Типы даты и времени, подходящие для представления меток времени, были добавлены в виде модуля datetime. Типы не поддерживают разные календари или множество навороченных функций и придерживаются основ представления времени.
Три основных типа: date (день, месяц и год), time (час, минута и секунда) и datetime, который содержит все атрибуты как date, так и time. Также есть класс timedelta, представляющий разницу между двумя моментами времени, а логика часовых поясов реализована классами, наследующими от абстрактного класса tzinfo.
Экземпляры date и time можно создать, передав именованные аргументы соответствующему конструктору, например datetime.date(year=1972, month=10, day=15), или используя один из нескольких методов класса. Например, метод класса date.today() возвращает текущую локальную дату.
После создания экземпляры классов даты/времени являются неизменяемыми. Существует ряд методов для создания форматированных строк из объектов:
>>> import datetime
>>> now = datetime.datetime.now()
>>> now.isoformat()
'2002-12-30T21:27:03.994956'
>>> now.ctime() # Доступно только для date, datetime
'Mon Dec 30 21:27:03 2002'
>>> now.strftime('%Y %d %b')
'2002 30 Dec'
Метод replace() позволяет изменить одно или несколько полей экземпляра date или datetime, возвращая новый экземпляр:
>>> d = datetime.datetime.now()
>>> d
datetime.datetime(2002, 12, 30, 22, 15, 38, 827738)
>>> d.replace(year=2001, hour = 12)
datetime.datetime(2001, 12, 30, 12, 15, 38, 827738)
>>>
Экземпляры можно сравнивать, хешировать и преобразовывать в строки (результат совпадает с результатом isoformat()). Экземпляры date и datetime можно вычитать друг из друга и складывать с экземплярами timedelta. Самый большой недостающий элемент – отсутствие поддержки в стандартной библиотеке разбора строк для получения экземпляра date или datetime.
За дополнительной информацией обращайтесь к справочной документации модуля. (Предоставлено Тимом Питерсом.)
Модуль optparse¶The optparse Module
Модуль getopt предоставляет простой разбор аргументов командной строки. Новый модуль optparse (первоначально назывался Optik) обеспечивает более сложный разбор командной строки, который следует соглашениям Unix, автоматически создает вывод для --help и может выполнять разные действия для разных опций.
Сначала создается экземпляр OptionParser, которому сообщается, какие опции есть у программы.
import sys
from optparse import OptionParser
op = OptionParser()
op.add_option('-i', '--input',
action='store', type='string', dest='input',
help='set input filename')
op.add_option('-l', '--length',
action='store', type='int', dest='length',
help='set maximum length of output')
Разбор командной строки выполняется вызовом метода parse_args().
options, args = op.parse_args(sys.argv[1:])
print options
print args
Метод возвращает объект, содержащий все значения параметров и список строк с остальными аргументами.
Теперь запуск скрипта с различными аргументами работает так, как и ожидается. Обратите внимание, что аргумент length автоматически преобразуется в целое число.
$ ./python opt.py -i data arg1
<Values at 0x400cad4c: {'input': 'data', 'length': None}>
['arg1']
$ ./python opt.py --input=data --length=4
<Values at 0x400cad2c: {'input': 'data', 'length': 4}>
[]
$
Справочное сообщение создаётся автоматически:
$ ./python opt.py --help
usage: opt.py [options]
options:
-h, --help show this help message and exit
-iINPUT, --input=INPUT
set input filename
-lLENGTH, --length=LENGTH
set maximum length of output
$
Подробнее см. документацию модуля.
Optik был написан Грегом Уордом (Greg Ward) с учётом предложений участников Getopt SIG.
Pymalloc: специализированный распределитель объектов¶Pymalloc: A Specialized Object Allocator
Pymalloc – специализированный распределитель объектов, написанный Владимиром Марангозовым, был добавлен в Python 2.1. Pymalloc предназначен для более быстрой работы, чем системный malloc(), и для меньших накладных расходов памяти при типичных для программ Python шаблонах выделения. Распределитель использует функцию malloc() из C для получения больших пулов памяти, а затем удовлетворяет мелкие запросы на выделение из этих пулов.
В версиях 2.1 и 2.2 pymalloc был экспериментальной функцией и не включался по умолчанию; его нужно было явно включить при компиляции Python, передав опцию --with-pymalloc скрипту configure. В версии 2.3 pymalloc получил дальнейшие улучшения и теперь включен по умолчанию; для его отключения нужно указать --without-pymalloc.
Для кода на Python это изменение незаметно, однако pymalloc может выявить ошибки в C-расширениях. Авторам модулей-расширений на C следует тестировать свой код с включённым pymalloc, поскольку некорректный код может приводить к аварийному завершению программы.
Существует одна особенно распространенная ошибка, вызывающая проблемы. В C API Python есть ряд функций выделения памяти, которые ранее были просто псевдонимами для malloc() и free() из библиотеки C; это означало, что если случайно вызвать несоответствующие функции, ошибка не будет заметна. Когда распределитель объектов включен, эти функции больше не являются псевдонимами malloc() и free(), и вызов неправильной функции для освобождения памяти может привести к аварийному дампу. Например, если память была выделена с помощью PyObject_Malloc(), ее нужно освобождать с помощью PyObject_Free(), а не free(). Некоторые модули, входящие в состав Python, столкнулись с этой проблемой и были исправлены; несомненно, есть и другие сторонние модули, имеющие ту же проблему.
В рамках этого изменения запутанные множественные интерфейсы для выделения памяти были объединены в два семейства API. Память, выделенная функциями одного семейства, не должна обрабатываться функциями другого. Одно семейство предназначено для выделения блоков памяти, другое – специально для выделения объектов Python.
- Для выделения и освобождения неспециализированного блока памяти используйте семейство «сырой памяти»: PyMem_Malloc(), PyMem_Realloc() и PyMem_Free().
- Семейство «объектной памяти» – это интерфейс к механизму pymalloc, описанному выше, и ориентировано на большое количество «мелких» выделений: PyObject_Malloc(), PyObject_Realloc() и PyObject_Free().
- Для выделения и освобождения объектов Python используйте семейство «объектных» функций: PyObject_New(), PyObject_NewVar() и PyObject_Del().
Благодаря большой работе Тима Питерса, pymalloc в версии 2.3 также предоставляет средства отладки для обнаружения перезаписи памяти и двойного освобождения как в модулях расширения, так и в самом интерпретаторе. Чтобы включить эту поддержку, скомпилируйте отладочную версию интерпретатора Python, запустив configure с опцией --with-pydebug.
В помощь разработчикам расширений в исходных кодах Python 2.3 распространяется заголовочный файл Misc/pymemcompat.h, который позволяет расширениям Python использовать интерфейсы выделения памяти версии 2.3 при компиляции с любой версией Python начиная с 1.5.2. Этот файл можно скопировать из дистрибутива исходных кодов Python и включить в исходный код своего расширения.
См. также
- http://svn.python.org/view/python/trunk/Objects/obmalloc.c
- Полные сведения о реализации pymalloc см. в комментариях в начале файла Objects/obmalloc.c в исходных кодах Python. Приведенная выше ссылка указывает на этот файл в SVN-обозревателе python.org.
Изменения в сборке и C API¶Build and C API Changes
Изменения процесса сборки Python и C API включают:
- Реализация обнаружения циклов, используемая сборщиком мусора, доказала свою стабильность, и теперь она обязательна. Невозможно скомпилировать Python без нее, а флаг --with-cycle-gc для configure был удален.
- Python теперь может быть опционально собран как разделяемая библиотека (libpython2.3.so) с помощью указания --enable-shared при запуске скрипта configure. (Автор: Ондрей Палковски.)
- Макросы DL_EXPORT и DL_IMPORT теперь устарели. Функции инициализации модулей расширения Python теперь должны объявляться с использованием нового макроса PyMODINIT_FUNC, в то время как ядро Python обычно использует макросы PyAPI_FUNC и PyAPI_DATA.
- Интерпретатор можно скомпилировать без строк документации для встроенных функций и модулей, передав --without-doc-strings скрипту configure. Это делает исполняемый файл Python примерно на 10% меньше, но также означает, что нельзя получить справку по встроенным модулям Python. (Автор: Густаво Нимейер.)
- Макрос PyArg_NoArgs() теперь устарел, и код, использующий его, следует изменить. Для Python 2.2 и новее таблица определений методов может указывать флаг METH_NOARGS, сигнализирующий об отсутствии аргументов; проверку аргументов можно удалить. Если важна совместимость с версиями Python до 2.2, код может использовать PyArg_ParseTuple(args, ""), но это будет медленнее, чем использование METH_NOARGS.
- PyArg_ParseTuple() принимает новые символы формата для различных размеров беззнаковых целых: B для unsigned char, H для unsigned short int, I для unsigned int и K для unsigned long long.
- Была добавлена новая функция PyObject_DelItemString(mapping, char *key) как сокращение для PyObject_DelItem(mapping, PyString_New(key)).
- Файловые объекты теперь по-другому управляют своим внутренним строковым буфером, увеличивая его экспоненциально при необходимости. В результате тесты производительности в Lib/test/test_bufio.py существенно ускорились (с 57 секунд до 1,7 секунды по одному из измерений).
- Теперь можно определять методы класса и статические методы для типа расширения C, устанавливая флаги METH_CLASS или METH_STATIC в структуре PyMethodDef метода.
- Python теперь включает копию исходного кода Expat XML-парсера, устраняя зависимость от системной версии или локальной установки Expat.
- Если вы динамически выделяете объекты типов в своём расширении, следует учитывать изменение правил, касающихся атрибутов __module__ и __name__. Вкратце: необходимо убедиться, что словарь типа содержит ключ '__module__'; делать имя модуля частью имени типа до последней точки больше не будет желаемого эффекта. Подробнее см. в справочной документации по API или в исходном коде.
Изменения, специфичные для платформ¶Port-Specific Changes
Поддержка порта для IBM OS/2 с использованием среды выполнения EMX была объединена в основное дерево исходных кодов Python. EMX – это уровень эмуляции POSIX поверх системных API OS/2. Порт Python для EMX пытается поддерживать все возможности, подобные POSIX, предоставляемые средой EMX, и в основном это удается; fork() и fcntl() ограничены ограничениями нижележащего уровня эмуляции. Стандартный порт OS/2, использующий компилятор IBM Visual Age, также получил поддержку чувствительной к регистру семантики импорта в рамках интеграции порта EMX в CVS. (Автор: Эндрю Макинтайр.)
В MacOS большинство модулей toolbox были слабо связаны для улучшения обратной совместимости. Это означает, что модули больше не будут загружаться с ошибкой, если в текущей версии ОС отсутствует отдельная процедура. Вместо этого вызов отсутствующей процедуры вызовет исключение. (Автор: Jack Jansen.)
RPM spec-файлы, находящиеся в каталоге Misc/RPM/ в дистрибутиве исходных кодов Python, были обновлены для версии 2.3. (Автор: Шон Райфшнайдер.)
Другие новые платформы, теперь поддерживаемые Python, включают AtheOS (http://www.atheos.cx/), GNU/Hurd и OpenVMS.
Другие изменения и исправления¶Other Changes and Fixes
Как обычно, по всему дереву исходных кодов было разбросано множество других улучшений и исправлений ошибок. Поиск по журналам изменений CVS показывает, что между Python 2.2 и 2.3 было применено 523 патча и исправлено 514 ошибок. Оба числа, вероятно, занижены.
Некоторые из наиболее заметных изменений:
Если установлена переменная окружения PYTHONINSPECT, интерпретатор Python войдет в интерактивный режим после выполнения программы Python, как если бы Python был запущен с опцией -i. Переменная окружения может быть установлена до запуска интерпретатора Python или может быть установлена самой программой Python в процессе выполнения.
Скрипт regrtest.py теперь предоставляет способ указать «все ресурсы, кроме foo». Имя ресурса, переданное опции -u, теперь может начинаться с дефиса ('-'), что означает «удалить этот ресурс». Например, опция '-uall,-bsddb' может быть использована для включения всех ресурсов, кроме bsddb.
Инструменты, используемые для сборки документации, теперь работают в Cygwin, а также в Unix.
Опкод SET_LINENO был удален. В далеком прошлом этот опкод был нужен для генерации номеров строк в трассировке и поддержки функций трассировки (например, pdb). Начиная с Python 1.5 номера строк в трассировке вычисляются с помощью другого механизма, который работает при «python -O». Для Python 2.3 Майкл Хадсон реализовал аналогичную схему для определения момента вызова функции трассировки, полностью устранив необходимость в SET_LINENO.
Было бы трудно заметить какую-либо разницу в коде Python, за исключением небольшого ускорения при запуске Python без -O.
Расширения C, обращающиеся к полю f_lineno объектов фрейма, должны вместо этого вызывать PyCode_Addr2Line(f->f_code, f->f_lasti). Это также позволит коду работать должным образом под «python -O» в более ранних версиях Python.
Отличная новая возможность: функции трассировки теперь могут присваивать значение атрибуту f_lineno объектов фрейма, изменяя строку, которая будет выполнена следующей. В отладчик pdb была добавлена команда jump, использующая эту новую возможность. (Реализовано Ричи Хиндлом.)
Перенос на Python 2.3¶Porting to Python 2.3
В этом разделе перечислены описанные ранее изменения, которые могут потребовать изменения кода:
yield теперь является ключевым словом; если оно используется в коде как имя переменной, необходимо выбрать другое имя.
Для строк X и Y выражение X in Y теперь работает, если X длиннее одного символа.
Конструктор типа int() теперь будет возвращать длинное целое вместо того, чтобы вызывать OverflowError, когда строка или число с плавающей запятой слишком велики, чтобы поместиться в целое.
Если у вас есть строки Unicode, содержащие 8-битные символы, вы должны объявить кодировку файла (UTF-8, Latin-1 или любую другую), добавив комментарий в начало файла. См. раздел PEP 263: Кодировки исходного кода для получения дополнительной информации.
Вызов методов Tcl через _tkinter больше не возвращает только строки. Вместо этого, если Tcl возвращает другие объекты, они преобразуются в соответствующий эквивалент на Python, если таковой существует, или оборачиваются объектом _tkinter.Tcl_Obj, если эквивалента на Python нет.
Большие восьмеричные и шестнадцатеричные литералы, такие как 0xffffffff, теперь вызывают FutureWarning. В настоящее время они хранятся как 32-битные числа и дают отрицательное значение, но в Python 2.4 они станут положительными длинными целыми.
Есть несколько способов исправить это предупреждение. Если требуется положительное число, просто добавьте L в конец литерала. Если нужно получить 32-битное целое с установленными младшими битами и ранее использовалось выражение вроде ~(1 << 31), вероятно, понятнее всего начать со всеми установленными битами и сбросить нужные старшие биты. Например, чтобы сбросить только старший бит (бит 31), можно написать 0xffffffffL &~(1L<<31).
Больше нельзя отключить утверждения, присваивая значение __debug__.
Функция setup() из Distutils получила несколько новых именованных аргументов, таких как depends. Старые версии Distutils аварийно завершатся, если передать им неизвестные ключевые слова. Одно из решений – проверить наличие новой функции get_distutil_options() в setup.py и использовать новые ключевые слова только с версией Distutils, которая их поддерживает:
from distutils import core kw = {'sources': 'foo.c', ...} if hasattr(core, 'get_distutil_options'): kw['depends'] = ['foo.h'] ext = Extension(**kw)
Использование None в качестве имени переменной теперь будет вызывать SyntaxWarning предупреждение.
Имена типов расширений, определённых модулями, входящими в состав Python, теперь содержат модуль и '.' перед именем типа.
Благодарности¶Acknowledgements
Автор хотел бы поблагодарить следующих людей за предложения, исправления и помощь с различными черновиками этой статьи: 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.