Что нового в Python 2.4¶
Автор: | А.М. Кухлинг |
---|
В этой статье объясняются новые возможности Python 2.4.1, выпущенного 30 марта 2005 г.
Python 2.4 — это релиз среднего размера. В нем не так много изменений, как в радикальном Python 2.2, но представлено больше возможностей, чем в консервативном выпуске 2.3. Наиболее важными новыми возможностями языка являются декораторы функций и генераторы выражений; большинство других изменений относятся к стандартной библиотеке.
Согласно журналам изменений CVS, между Python 2.3 и 2.4 был применен 481 патч и исправлено 502 ошибки. Обе цифры, вероятно, занижены.
В этой статье не делается попытка предоставить полную спецификацию каждой новой функции, а вместо этого дается краткое введение в каждую функцию. Для получения полной информации вы должны обратиться к документации по Python 2.4, такой как Справочник по библиотеке Python и Справочное руководство по Python. Часто вас будут направлять к PEP для новой функции для объяснения реализации и обоснования дизайна.
PEP 218: встроенные объекты множества¶
Python 2.3 представил модуль sets
. Реализации заданных типов данных на C
теперь добавлены в ядро Python в виде двух новых встроенных типов,
set(iterable)
и frozenset(iterable)
. Они обеспечивают высокоскоростные
операции для проверки принадлежности, удаления дубликатов из
последовательностей и математических операций, таких как объединения,
пересечения, разности и симметричные разности.
>>> a = set('abracadabra') # сформировать множество из строки
>>> 'z' in a # быстрое тестирование членства
False
>>> a # уникальные буквы в a
set(['a', 'r', 'b', 'c', 'd'])
>>> ''.join(a) # преобразовать обратно в строку
'arbcd'
>>> b = set('alacazam') # сформировать второй множество
>>> a - b # буквы в a, но не в b
set(['r', 'd', 'b'])
>>> a | b # буквы a или b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # буквы a и b
set(['a', 'c'])
>>> a ^ b # буквы в a или b, но не в обоих
set(['r', 'd', 'b', 'm', 'z', 'l'])
>>> a.add('z') # добавить новый элемент
>>> a.update('wxy') # добавить несколько новых элементов
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])
>>> a.remove('x') # убрать один элемент
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])
Тип frozenset()
является неизменяемой версией set()
. Поскольку он
неизменяем и хешируем, его можно использовать как ключ словаря или как член
другого набора.
Модуль sets
остаётся в стандартной библиотеке и может быть полезен, если
вы хотите создать подкласс классов Set
или ImmutableSet
. В
настоящее время нет планов по прекращению поддержки модуля.
См.также
- PEP 218 — Добавление встроенного типа объекта Set
- Первоначально предложено Грегом Уилсоном и в конечном итоге реализовано Рэймондом Хеттингер.
PEP 237: Объединение длинных целых и целых чисел¶
Длительный процесс перехода для этого PEP, начатый в Python 2.2, делает ещё
один шаг вперед в Python 2.4. В версии 2.3 некоторые целочисленные операции,
которые после объединения int/long вели себя по-другому, вызывали
предупреждения FutureWarning
и возвращали значения, ограниченные 32 или
64 битами (в зависимости от вашей платформы). В версии 2.4 данные выражения
больше не выдают предупреждение, а вместо этого выдают другой результат,
который обычно представляет собой длинное целое число.
Проблемные выражения — это прежде всего сдвиги влево и длинные
шестнадцатеричные и восьмеричные константы. Например, 2 << 32
приводит к
предупреждению в версии 2.3, которое вычисляется как 0 на 32-разрядных
платформах. В Python 2.4 это выражение теперь возвращает правильный ответ —
8589934592.
См.также
- PEP 237 — Объединение длинных целых чисел и целых чисел
- Оригинальный PEP, написанный Моше Задкой и GvR. Изменения для 2.4 были реализованный Калле Свенссон.
PEP 289: выражения генератора¶
Функция итератора, представленная в Python 2.2, и модуль itertools
упрощают написание программ, которые циклически перебирают большие наборы
данных, не сохраняя весь множество данных в памяти одновременно. Генераторы
списков не очень хорошо вписываются в эту картину, потому что они создают
объект списка Python, содержащий все элементы. Это неизбежно вытягивает все
объекты в память, что может быть проблемой, если ваш множество данных очень
большой. При попытке написать программу в функциональном стиле было бы
естественно написать что-то вроде:
links = [link for link in get_all_links() if not link.followed]
for link in links:
...
вместо
for link in get_all_links():
if link.followed:
continue
...
Первая форма более краткая и, возможно, более удобочитаемая, но если вы имеете дело с большим количеством объектов ссылок, вам придется написать вторую форму, чтобы избежать одновременного хранения всех объектов ссылок в памяти.
Выражения-генераторы работают так же, как и генераторы списков, но не материализуют весь список; вместо этого они создают генератор, который будет возвращать элементы один за другим. Приведённый выше пример можно записать как:
links = (link for link in get_all_links() if not link.followed)
for link in links:
...
Выражения генератора всегда должны быть написаны внутри круглых скобок, как в приведённом выше примере. Круглые скобки, сигнализирующие о вызове функции, также учитываются, поэтому, если вы хотите создать итератор, который будет немедленно передан функции, которую вы можете написать:
print sum(obj.count for obj in list_all_objects())
Генераторные выражения отличаются от списковых включений несколькими небольшими способами. В частности, переменная цикла (obj в приведённом выше примере) недоступна вне выражения генератора. Включение списка оставляет переменной присвоенное её последнее значение; в будущих версиях Python это изменится, и в этом отношении выражения списков будут соответствовать выражениям генератора.
См.также
- PEP 289 — генератор выражений
- Предложено Рэймондом Хеттингером и реализовано Дживон Сео с ранними усилиями под управлением Хе-Шик Чанг.
PEP 292: более простые замены строк¶
Некоторые новые классы в стандартной библиотеке предоставляют альтернативный механизм замены переменных строками; данный стиль замены может быть лучше для приложений, где неподготовленным пользователям необходимо редактировать шаблоны.
Обычным способом замены переменных по имени является оператор %
:
>>> '%(page)i: %(title)s' % {'page':2, 'title': 'The Best of Times'}
'2: The Best of Times'
При написании строки шаблона можно легко забыть i
или s
после
закрывающей скобки. Это не большая проблема, если шаблон находится в модуле
Python, потому что вы запускаете код, получаете «символ неподдерживаемого
формата» ValueError
и устраняете проблему. Однако рассмотрим такое
приложение, как Mailman, в котором строки шаблонов или переводы редактируются
пользователями, не знакомыми с языком Python. Синтаксис строки форматирования
сложно объяснить таким пользователям, а если они допустят ошибку, им будет
трудно предоставить полезную обратную связь.
PEP 292 добавляет класс Template
к модулю string
, который
использует $
для обозначения замены:
>>> import string
>>> t = string.Template('$page: $title')
>>> t.substitute({'page':2, 'title': 'The Best of Times'})
'2: The Best of Times'
Если в словаре отсутствует ключ, метод substitute()
вызовет ошибку
KeyError
. Существует также метод safe_substitute()
, игнорирующий
отсутствующие ключи:
>>> t = string.Template('$page: $title')
>>> t.safe_substitute({'page':3})
'3: $title'
См.также
- PEP 292 — более простые замены строк
- Написано и реализовано Барри Варшавой.
PEP 318: Декораторы для функций и методов¶
Python 2.2 расширил объектную модель Python, добавив статические методы и
методы класса, но не расширил синтаксис Python, чтобы предоставить какой-либо
новый способ определения статических методов или методов класса. Вместо этого
вам нужно было написать оператор def
обычным способом и передать
результирующий метод функции staticmethod()
или classmethod()
,
которая завершит функцию как метод нового типа. Ваш код будет выглядеть так:
class C:
def meth (cls):
...
meth = classmethod(meth) # Перепривязать имя к методу класса в оболочке
Если бы метод был очень длинным, было бы легко пропустить или забыть вызов
classmethod()
после тела функции.
Намерение всегда состояло в том, чтобы добавить некоторый синтаксис, чтобы сделать такие определения более удобочитаемыми, но во время релиза 2.2 хороший синтаксис не был очевиден. Сегодня хороший синтаксис still не очевиден, но пользователи просят упростить доступ к этой функции; для удовлетворения этой потребности была добавлена новая синтаксическая функция.
Новая функция называется «декораторы функций». Название происходит от идеи, что
classmethod()
, staticmethod()
и друзья хранят дополнительную
информацию об объекте функции; это функции decorating с более подробной
информацией.
Обозначение заимствовано из Java и использует символ '@'
в качестве
индикатора. Используя новый синтаксис, приведённый выше пример будет написан:
class C:
@classmethod
def meth (cls):
...
@classmethod
является сокращением для назначения
meth=classmethod(meth)
. В более общем случае, если у вас есть следующее:
@A
@B
@C
def f ():
...
Это эквивалентно следующему коду перед декоратором:
def f(): ...
f = A(B(C(f)))
Декораторы должны находиться в строке перед определением функции, по одному
декоратору в строке, и не могут находиться в той же строке, что и оператор def,
что означает, что @A def f(): ...
является недопустимым. Вы можете
декорировать определения функций только на уровне модуля или внутри класса; вы
не можете декорировать определения классов.
Декоратор — это просто функция, которая принимает декорируемую функцию в качестве аргумента и возвращает либо ту же функцию, либо какой-то новый объект. Возвращаемое значение декоратора не обязательно должно вызываться (хотя обычно это так), если только к результату не будут применены дополнительные декораторы. Легко написать свои собственные декораторы. В следующем простом примере просто устанавливается атрибут объекта функции:
>>> def deco(func):
... func.attr = 'decorated'
... return func
...
>>> @deco
... def f(): pass
...
>>> f
<function f at 0x402ef0d4>
>>> f.attr
'decorated'
>>>
В качестве немного более реалистичного примера следующий декоратор проверяет, что предоставленный аргумент является целым числом:
def require_int (func):
def wrapper (arg):
assert isinstance(arg, int)
return func(arg)
return wrapper
@require_int
def p1 (arg):
print arg
@require_int
def p2(arg):
print arg*2
Пример в PEP 318 содержит более сложную версию этой идеи, которая позволяет вам как указать требуемый тип, так и проверить возвращаемый тип.
Функции-декораторы могут принимать аргументы. Если аргументы предоставлены,
ваша функция-декоратор вызывается только с этими аргументами и должна
возвращать новую функцию-декоратор; данная функция должна принимать одну
функцию и возвращать функцию, как приведено ранее. Другими словами, @A @B
@C(args)
становится:
def f(): ...
_deco = C(args)
f = A(B(_deco(f)))
Сделать это правильно может быть немного сложно, но это не так уж сложно.
Небольшое связанное изменение делает атрибут функций func_name
доступным для записи. Данный атрибут используется для отображения имён функций
в обратных трассировках, поэтому декораторы должны изменить имя любой новой
функции, которая создаётся и возвращается.
См.также
- PEP 318 — Декораторы для функций, методов и классов
- Написано Кевином Д. Смитом, Джимом Джуэттом и Скипом Монтанаро. Несколько человек писал патчи реализующие декораторы функций, но тот что был на самом деле был зарегистрирован патч № 979728, написанный Марком Расселом.
- https://wiki.python.org/moin/PythonDecoratorLibrary
- Вики-страница содержит несколько примеров декораторов.
PEP 322: обратная итерация¶
Новая встроенная функция reversed(seq)
принимает последовательность и
возвращает итератор, который перебирает элементы последовательности в обратном
порядке.
>>> for i in reversed(xrange(1,4)):
... print i
...
3
2
1
По сравнению с расширенной нарезкой, такой как range(1,4)[::-1]
,
reversed()
легче читается, работает быстрее и использует значительно
меньше памяти.
Обратите внимание, что reversed()
принимает только последовательности, а
не произвольные итераторы. Если вы хотите обратить итератор, сначала
преобразовать его в список с list()
.
>>> input = open('/etc/passwd', 'r')
>>> for line in reversed(list(input)):
... print line
...
root:*:0:0:System Administrator:/var/root:/bin/tcsh
...
См.также
- PEP 322 — Обратная итерация
- Написано и реализовано Рэймондом Хеттингером.
PEP 324: новый модуль subprocess¶
Стандартная библиотека предоставляет несколько способов выполнения подпроцесса,
предлагающих различные функции и разные уровни сложности.
os.system(command)
прост в использовании, но медленный (он запускает
процесс оболочки, который выполняет команду) и опасный (вы должны быть
осторожны, чтобы избежать метасимволов оболочки). Модуль popen2
предлагает классы, которые могут захватывать стандартный вывод и стандартные
ошибки из подпроцесса, но названия сбивают с толку. Модуль subprocess
убирает это, предоставляя унифицированный интерфейс, предлагающий все функции,
которые могут вам понадобиться.
Вместо набора классов popen2
subprocess
содержит один класс с
именем Popen
, конструктор которого поддерживает ряд различных ключевых
аргументов.
class Popen(args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=False, shell=False,
cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0):
args обычно представляет собой последовательность строк, которые будут
аргументами программы, выполняемой как подпроцесс. (Если аргумент shell
верен, args может быть строкой, которая затем будет передана оболочке для
интерпретации, как это делает os.system()
.)
stdin, stdout и stderr указывают, какими будут потоки ввода, вывода и
ошибок подпроцесса. Вы можете предоставить файловый объект или файловый
дескриптор, или вы можете использовать константу subprocess.PIPE
для
создания канала между подпроцессом и родителем.
Конструктор имеет ряд удобных опций:
- close_fds запрашивает закрытие всех файловых дескрипторов перед запуском подпроцесса.
- cwd указывает рабочий каталог, в котором будет выполняться подпроцесс (по умолчанию любой рабочий каталог родителя).
- env — это словарь, определяющий переменные среды.
- preexec_fn — это функция, которая вызывается перед запуском дочернего элемента.
- preexec_fn — это функция, которая вызывается перед запуском дочернего элемента.
Создав экземпляр Popen
, вы можете вызвать его метод wait()
для
приостановки до завершения подпроцесса, poll()
для проверки выхода без
паузы или communicate(data)
для отправки строки data на стандартный ввод
подпроцесса. Затем communicate(data)
считывает любые данные, отправленные
подпроцессом на стандартный вывод или стандартную ошибку, возвращая кортеж
(stdout_data, stderr_data)
.
call()
— это ярлык, который передает свои аргументы конструктору
Popen
, ожидает завершения команды и возвращает код состояния
подпроцесса. Может служить более безопасным аналогом os.system()
:
sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
if sts == 0:
# Успешно
...
else:
# dpkg вернул ошибку
...
Команда вызывается без использования оболочки. Если вы действительно хотите
использовать оболочку, вы можете добавить shell=True
в качестве ключевого
аргумента и указать строку вместо последовательности:
sts = subprocess.call('dpkg -i /tmp/new-package.deb', shell=True)
PEP принимает различные примеры кода оболочки и Python и показывает, как их можно
преобразовать в код Python, использующий subprocess
. Настоятельно
рекомендуется прочитать данный раздел PEP.
См.также
- PEP 324 — subprocess — Новый модуль процесса
- Написано и реализовано Питером Астрандом при содействии Фредрика Лунда и другие.
PEP 327: десятичный тип данных¶
Python всегда поддерживал числа с плавающей запятой (FP) на основе базового
типа C double
в качестве типа данных. Однако, хотя большинство языков
программирования предоставляют тип с плавающей запятой, многие люди (даже
программисты) не знают, что числа с плавающей запятой не точно представляют
определённые десятичные дроби. Новый тип Decimal
может точно
представлять данные дроби, вплоть до указанного пользователем предела точности.
Зачем нужна десятичная дробь?¶
Появляются ограничения из-за представления, используемого для чисел с плавающей запятой. Числа FP состоят из трех компонентов:
- Знак, положительный или отрицательный.
- Мантисса, представляющая собой однозначное двоичное число, за которым следует
дробная часть. Например,
1.01
в системе счисления по основанию 2 равно1 + 0/2 + 1/4
или 1,25 в десятичной системе счисления. - Показатель степени, указывающий, где находится десятичная точка в представленном числе.
Например, число 1,25 имеет положительный знак, значение мантиссы равно 1,01 (в двоичном формате) и показатель степени равен 0 (десятичную точку сдвигать не нужно). Число 5 имеет тот же знак и мантиссу, но показатель степени равен 2, потому что мантисса умножается на 4 (2 в степени степени 2); 1,25 * 4 равно 5.
Современные системы обычно обеспечивают поддержку операций с плавающей запятой,
которая соответствует стандарту IEEE 754. Тип C double
обычно
реализуется как 64-битное число IEEE 754, в котором для мантиссы используется
52 бита пространства. Это означает, что числа могут быть указаны только с
точностью до 52 бит. Если вы пытаетесь представить числа, расширение которых
повторяется бесконечно, расширение обрывается после 52 бит. К сожалению,
большинству программ необходимо производить выходные данные в десятичной
системе счисления, а обыкновенные дроби в десятичной системе счисления часто
повторяют десятичные числа в двоичном формате. Например, десятичное число 1.1 —
это двоичное число 1.0001100110011 ...
; .1 = 1/16 + 1/32 + 1/256 плюс
бесконечное количество дополнительных членов. IEEE 754 должен отсечь это
бесконечно повторяющееся десятичное число после 52 цифр, поэтому представление
немного неточное.
Иногда можно увидеть эту неточность при печати числа:
>>> 1.1
1.1000000000000001
Неточность не всегда видна, когда вы печатаете число, потому что преобразование FP в десятичную строку обеспечивается библиотекой C, а большинство библиотек C пытаются произвести разумный вывод. Однако даже если она не отображается, неточность все ещё присутствует, и последующие операции могут увеличить ошибку.
Для многих приложений это не имеет значения. Если я рисую точки и отображаю их на своём мониторе, разница между 1.1 и 1.1000000000000001 слишком мала, чтобы её можно было увидеть. Отчеты часто ограничивают вывод определенным числом знаков после запятой, и если округлить число до двух, трех или даже восьми знаков после запятой, ошибка никогда не будет видна. Однако для приложений, где это имеет значение, реализация собственных арифметических процедур требует больших усилий.
Следовательно, был создан тип Decimal
.
Тип Decimal
¶
В стандартную библиотеку Python был добавлен новый модуль decimal
. Он
содержит два класса: Decimal
и Context
. Экземпляры
Decimal
представляют числа, а экземпляры Context
используются
для переноса различных параметров, таких как точность и режим округления по
умолчанию.
Экземпляры Decimal
неизменяемы, как обычные целые числа Python и числа
FP; как только он будет создан, вы не сможете изменить значение, которое
представляет экземпляр. Экземпляры Decimal
могут быть созданы из целых
чисел или строк:
>>> import decimal
>>> decimal.Decimal(1972)
Decimal("1972")
>>> decimal.Decimal("1.1")
Decimal("1.1")
Вы также можете предоставить кортежи, содержащие знак, мантиссу, представленную в виде кортежа десятичных цифр, и показатель степени:
>>> decimal.Decimal((1, (1, 4, 7, 5), -2))
Decimal("-14.75")
Предостережение: бит знака — это логическое значение, поэтому 0 — положительное значение, а 1 — отрицательное.
Преобразование из чисел с плавающей запятой создаёт небольшую проблему: должно
ли число FP, представляющее 1,1, превращаться в десятичное число точно для 1,1
или для 1,1 плюс любые неточности? Было решено обойти эту проблему и оставить
такое преобразование вне API. Вместо этого следует преобразовать число с
плавающей запятой в строку с требуемой точностью и передать строку конструктору
Decimal
:
>>> f = 1.1
>>> decimal.Decimal(str(f))
Decimal("1.1")
>>> decimal.Decimal('%.12f' % f)
Decimal("1.100000000000")
Когда у вас есть экземпляры Decimal
, вы можете выполнять над ними
обычные математические операции. Одно ограничение: для возведения в степень
требуется целочисленный показатель степени:
>>> a = decimal.Decimal('35.72')
>>> b = decimal.Decimal('1.73')
>>> a+b
Decimal("37.45")
>>> a-b
Decimal("33.99")
>>> a*b
Decimal("61.7956")
>>> a/b
Decimal("20.64739884393063583815028902")
>>> a ** 2
Decimal("1275.9184")
>>> a**b
Traceback (most recent call last):
...
decimal.InvalidOperation: x ** (non-integer)
Вы можете комбинировать экземпляры Decimal
с целыми числами, но не с
числами с плавающей запятой:
>>> a + 4
Decimal("39.72")
>>> a + 4.5
Traceback (most recent call last):
...
TypeError: You can interact Decimal only with int, long or Decimal data types.
>>>
Числа Decimal
можно использовать с модулями math
и
cmath
, но обратите внимание, что они будут немедленно преобразованы в
числа с плавающей запятой до выполнения операции, что может привести к потере
точности и аккуратности. Вы также получить обычное число с плавающей запятой, а
не Decimal
.
>>> import math, cmath
>>> d = decimal.Decimal('123456789012.345')
>>> math.sqrt(d)
351364.18288201344
>>> cmath.sqrt(-d)
351364.18288201344j
Экземпляры Decimal
имеют метод sqrt()
, который возвращает
Decimal
, но если вам нужны другие вещи, такие как тригонометрические
функции, вам придется их реализовать.
>>> d.sqrt()
Decimal("351364.1828820134592177245001")
Тип Context
¶
Экземпляры класса Context
инкапсулируют несколько параметров для
десятичных операций:
prec
— это точность, количество знаков после запятой.rounding
определяет режим округления. Модульdecimal
имеет константы для различных возможностей:ROUND_DOWN
,ROUND_CEILING
,ROUND_HALF_EVEN
и другие.traps
— это словарь, определяющий, что происходит при возникновении определенных условий ошибки: либо вызывается исключение, либо возвращается значение. Некоторыми примерами ошибок являются деление на ноль, потеря точности и переполнение.
Существует локальный контекст потока по умолчанию, доступный при вызове
getcontext()
; вы можете изменить свойства этого контекста, чтобы изменить
точность по умолчанию, округление или обработку прерываний. В следующем примере
показан эффект изменения точности контекста по умолчанию:
>>> decimal.getcontext().prec
28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.1428571428571428571428571429")
>>> decimal.getcontext().prec = 9
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.142857143")
Можно выбрать действие по умолчанию для условий ошибки; модуль может либо возвращать специальное значение, такое как бесконечность или не-число, либо могут вызываться исключения:
>>> decimal.Decimal(1) / decimal.Decimal(0)
Traceback (most recent call last):
...
decimal.DivisionByZero: x / 0
>>> decimal.getcontext().traps[decimal.DivisionByZero] = False
>>> decimal.Decimal(1) / decimal.Decimal(0)
Decimal("Infinity")
>>>
Экземпляр Context
также имеет различные методы форматирования чисел,
такие как to_eng_string()
и to_sci_string()
.
Дополнительные сведения см. в документации по модулю decimal
, которая
включает краткое руководство и справку.
См.также
- PEP 327 — десятичный тип данных
- Написано Факундо Батистой и реализовано Факундо Батистой, Эриком Прайсом Рэймонд Хеттингер, Ааз и Тим Питерс.
- http://www.lahey.com/float.htm
- В статье используется код Fortran для иллюстрации многих проблем, в которых неточность с плавающей запятой может проявиться.
- http://speleotrove.com/decimal/
- Описание десятичного представления. Это представление существует предлагается в качестве стандарта и лежит в основе нового десятичного типа Python. Многое из этого материал был написан Майком Каулишоу, разработчиком языка Rexx.
PEP 328: Многострочный импорт¶
Одно языковое изменение представляет собой небольшую синтаксическую настройку,
направленную на упрощение импорта многих имён из модуля. В операторе from
module import names
names — это последовательность имён, разделенных
запятыми. Если последовательность очень длинная, вы можете либо написать
несколько импортов из одного и того же модуля, либо использовать обратную косую
черту, чтобы экранировать окончания строк, подобные этому:
from SimpleXMLRPCServer import SimpleXMLRPCServer,\
SimpleXMLRPCRequestHandler,\
CGIXMLRPCRequestHandler,\
resolve_dotted_attribute
Синтаксическое изменение в Python 2.4 просто позволяет заключать имена в круглые скобки. Python игнорирует символы новой строки в выражении в скобках, поэтому обратная косая черта больше не нужна:
from SimpleXMLRPCServer import (SimpleXMLRPCServer,
SimpleXMLRPCRequestHandler,
CGIXMLRPCRequestHandler,
resolve_dotted_attribute)
PEP также предлагает, чтобы все операторы import
были абсолютным
импортом, а начальный символ .
указывал на относительный импорт. Часть
PEP не была реализована для Python 2.4, но была завершена для Python 2.5.
См.также
- PEP 328 — Импорт: многострочный и абсолютный/относительный
- Автор Ааз. Многострочный импорт реализовал Дима Дорфман.
PEP 331: Независимые от локали преобразования с плавающей точкой/строкой¶
Модули locale
позволяют программному обеспечению Python выбирать
различные преобразования и соглашения об отображении, локализованные для
определенной страны или языка. Однако модуль старался не менять числовой
языковой стандарт, поскольку различные функции в реализации Python требовали,
чтобы числовой языковой стандарт оставался установленным на 'C'
. Часто это
происходило потому, что код использовал функцию atof()
библиотеки C.
Однако отсутствие числовой локали вызывало проблемы с расширениями, использующими сторонние библиотеки C, поскольку они не имели правильной установки локали. Мотивирующим примером был GTK+, чьи виджеты пользовательского интерфейса не отображали числа в текущей локали.
Решение, описанное в PEP, состоит в том, чтобы добавить в API Python три новые функции, которые выполняют преобразования только для ASCII, игнорируя настройку локали:
PyOS_ascii_strtod(str, ptr)
иPyOS_ascii_atof(str, ptr)
преобразуют строку в Cdouble
.PyOS_ascii_formatd(buffer, buf_len, format, d)
преобразуетdouble
в строку ASCII.
Код для данных функций взят из библиотеки GLib
(https://developer.gnome.org/glib/stable/), разработчики которой любезно
перелицензировали соответствующие функции и передали их в дар Python Software
Foundation. Модуль locale
теперь может изменять числовую локаль,
позволяя таким расширениям, как GTK+, выдавать правильные результаты.
См.также
- PEP 331 — преобразование чисел с плавающей запятой в строку, не зависящее от локали
- Написано Кристианом Р. Рейсом и реализовано Густаво Карнейро.
Другие языковые изменения¶
Вот все изменения, которые Python 2.4 вносит в основной язык Python.
Добавлены декораторы для функций и методов (PEP 318).
Добавлены встроенные типы
set()
иfrozenset()
(PEP 218). Другие новые встроенные функции включают функциюreversed(seq)
(PEP 322).Добавлены выражения генератора (PEP 289).
Некоторые числовые выражения больше не возвращают значения, ограниченные 32 или 64 битами (PEP 237).
Теперь вы можете заключать в скобки список имён в выражении
from module import names
(PEP 328).Метод
dict.update()
теперь принимает те же формы аргументов, что и конструкторdict
. Это включает в себя любое сопоставление, любую итерацию пар ключ/значение и ключевые аргументы. (Предоставлено Рэймондом Хеттингером)Строковые методы
ljust()
,rjust()
иcenter()
теперь принимают необязательный аргумент для указания символа заполнения, отличного от пробела. (Предоставлено Рэймондом Хеттингером.)Строки также получили метод
rsplit()
, который работает так же, как методsplit()
, но отделяется от конца строки. (Предоставлено Шоном Райфшнайдером.)>>> 'www.python.org'.split('.', 1) ['www', 'python.org'] 'www.python.org'.rsplit('.', 1) ['www.python', 'org']
В метод списков
sort()
были добавлены три ключевых параметра: cmp, key и reverse. Данные параметры упрощают некоторые распространенные способы использованияsort()
. Все данные параметры являются необязательными.Для параметра cmp значение должно быть функцией сравнения, которая принимает два параметра и возвращает -1, 0 или +1 в зависимости от того, как сравниваются параметры. Затем данная функция будет использоваться для сортировки списка. Ранее это был единственный параметр, который можно было передать
sort()
.key должна быть функцией с одним параметром, которая принимает элемент списка и возвращает ключ сравнения для этого элемента. Затем список сортируется с использованием ключей сравнения. В следующем примере список сортируется без учёта регистра:
>>> L = ['A', 'b', 'c', 'D'] >>> L.sort() # Сортировка с учётом регистра >>> L ['A', 'D', 'b', 'c'] >>> # Использование параметра 'key' для сортировки списка >>> L.sort(key=lambda x: x.lower()) >>> L ['A', 'b', 'c', 'D'] >>> # Старомодный способ >>> L.sort(cmp=lambda x,y: cmp(x.lower(), y.lower())) >>> L ['A', 'b', 'c', 'D']
Последний пример, в котором используется параметр cmp, — это старый способ выполнения сортировки без учета регистра. Он работает, но медленнее, чем при использовании параметра key. Использование key вызывает метод
lower()
один раз для каждого элемента в списке, а использование cmp вызывает его дважды для каждого сравнения, поэтому использование key экономит вызовы методаlower()
.Для простых ключевых функций и функций сравнения часто можно избежать выражения
lambda
, используя вместо этого несвязанный метод. Например, описанную выше сортировку без учета регистра лучше всего записать как:>>> L.sort(key=str.lower) >>> L ['A', 'b', 'c', 'D']
Наконец, параметр reverse принимает логическое значение. Если значение равно истина, список будет отсортирован в обратном порядке. Вместо
L.sort(); L.reverse()
теперь можно писатьL.sort(reverse=True)
.Результаты сортировки теперь гарантированно стабильны. Это означает, что две записи с одинаковыми ключами будут возвращены в том же порядке, в котором они были введены. Например, вы можете отсортировать список людей по имени, а затем отсортировать список по возрасту, в результате чего будет отсортирован список по возрасту, в котором люди одного возраста будут отсортированы по имени.
(Все изменения в
sort()
внес Рэймонд Хеттингер.)Существует новая встроенная функция
sorted(iterable)
, которая работает как встроенный методlist.sort()
, но может использоваться в выражениях. Отличия есть:вход может быть любым итерируемым;
новообразованная копия сортируется, оставляя оригинал нетронутым; и
выражение возвращает новую отсортированную копию
>>> L = [9,7,8,3,2,4,1,6,5] >>> [10+i for i in sorted(L)] # может использоваться в списковом включении [11, 12, 13, 14, 15, 16, 17, 18, 19] >>> L # оригинал остаётся без изменений [9,7,8,3,2,4,1,6,5] >>> sorted('Monty Python') # любая итерация может быть входом [' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y'] >>> # Список содержимого словаря, отсортированного по ключевым значениям >>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5) >>> for k, v in sorted(colormap.iteritems()): ... print k, v ... black 4 blue 2 green 3 red 1 yellow 5
(Предоставлено Рэймондом Хеттингером.)
Целочисленные операции больше не будут вызывать ошибку
OverflowWarning
. ПредупреждениеOverflowWarning
исчезнет в Python 2.5.Интерпретатор получил новый переключатель
-m
, который получает имя, ищет соответствующий модуль вsys.path
и запускает модуль как сценарий. Например, теперь вы можете запустить профилировщик Python сpython -m profile
. (Предоставлено Ником Когланом.)Функции
eval(expr, globals, locals)
иexecfile(filename, globals, locals)
, а также операторexec
теперь принимают любой тип сопоставления для параметра locals. Раньше это должен был быть обычный словарь Python. (Предоставлено Рэймондом Хеттингером.)Встроенная функция
zip()
иitertools.izip()
теперь возвращают пустой список, если вызываются без аргументов. Ранее они вызывали исключениеTypeError
. Это делает их более подходящими для использования со списками аргументов переменной длины:>>> def transpose(array): ... return zip(*array) ... >>> transpose([(1,2,3), (4,5,6)]) [(1, 4), (2, 5), (3, 6)] >>> transpose([]) []
(Предоставлено Рэймондом Хеттингером.)
Сбой при импорте модуля больше не оставляет частично инициализированный объект модуля в
sys.modules
. Незавершенный объект модуля, оставленный позади, может обмануть дальнейший импорт того же модуля и привести к запутанным ошибкам. (Исправлено Тимом Питерсом.)None
теперь является константой; код, связывающий новое значение с именемNone
, теперь является синтаксической ошибкой. (Предоставлено Рэймондом Хеттингером)
Оптимизации¶
- Внутренние циклы для нарезки списков и кортежей были оптимизированы и теперь
работают примерно на треть быстрее. Внутренние циклы для словарей также были
оптимизированы, что привело к повышению производительности для
keys()
,values()
,items()
,iterkeys()
,itervalues()
иiteritems()
. (Предоставлено Рэймондом Хеттингером.) - Механизм для увеличения и уменьшения списков был оптимизирован для скорости и
эффективности использования пространства. Добавление и извлечение из списков
теперь выполняется быстрее благодаря более эффективным путям кода и менее
частому использованию базовой системы
realloc()
. Понимание списков также приносит пользу.list.extend()
также был оптимизирован и больше не преобразовывает свой аргумент во временный список перед расширением базового списка. (Предоставлено Рэймондом Хеттингером.) list()
,tuple()
,map()
,filter()
иzip()
теперь выполняются в несколько раз быстрее с аргументами, отличными от последовательности, которые предоставляют метод__len__()
. (Предоставлено Рэймондом Хеттингером.)- Методы
list.__getitem__()
,dict.__getitem__()
иdict.__contains__()
теперь реализованы как объектыmethod_descriptor
, а не как объектыwrapper_descriptor
. Эта форма доступа удваивает их производительность и делает их более подходящими для использования в качестве аргументов функционалов:map(mydict.__getitem__, keylist)
. (Предоставлено Рэймондом Хеттингером.) - Добавлен новый код операции
LIST_APPEND
, который упрощает сгенерированный байт-код для понимания списков и ускоряет их примерно на треть. (Предоставлено Рэймондом Хеттингером.) - Оптимизатор байт-кода глазка был улучшен для получения более короткого и быстрого байт-кода; примечательно, что полученный байт-код более читабелен. (Улучшено Рэймондом Хеттингером.)
- Конкатенация строк в операторах формы
s = s + "abc"
иs += "abc"
теперь выполняется более эффективно при определенных обстоятельствах. Эта оптимизация не будет присутствовать в других реализациях Python, таких как Jython, поэтому вам не следует на нее полагаться; использование метода строкjoin()
по-прежнему рекомендуется, если вы хотите эффективно склеить большое количество строк. (Предоставлено Армином Риго.)
Конечным результатом оптимизации 2.4 является то, что Python 2.4 выполняет тест pystone примерно на 5% быстрее, чем Python 2.3, и на 35% быстрее, чем Python 2.2. (pystone не является особенно хорошим эталоном, но это наиболее часто используемый показатель производительности Python. Ваши собственные приложения могут демонстрировать большие или меньшие преимущества от Python 2.4.)
Новые, улучшенные и устаревшие модули¶
Как обычно, стандартная библиотека Python получила ряд улучшений и исправлений
ошибок. Вот неполный список наиболее заметных изменений, отсортированных в
алфавитном порядке по имени модуля. Обратитесь к файлу Misc/NEWS
в
дереве исходных текстов, чтобы получить более полный список изменений, или
просмотрите журналы CVS для получения подробной информации.
Функция
loop()
модуляasyncore
теперь имеет параметр count, который позволяет выполнять ограниченное количество проходов через цикл опроса. По умолчанию по-прежнему зацикливается навсегда.Модуль
base64
теперь имеет более полную поддержку RFC 3548 для кодирования и декодирования Base64, Base32 и Base16, включая необязательное свертывание регистра и необязательные альтернативные алфавиты. (Предоставлено Барри Варшавой.)Модуль
bisect
теперь имеет базовую реализацию C для повышения производительности. (Предоставлено Дмитрием Васильевым.)Коллекции восточноазиатских кодеков CJKCodecs, поддерживаемые Hye-Shik Chang, были интегрированы в версию 2.4. Новые кодировки есть:
Китайский (PRC): gb2312, gbk, gb18030, big5hkscs, hz
Китайский (ROC): big5, cp950
- Японский: cp932, euc-jis-2004, euc-jp, euc-jisx0213, iso-2022-jp,
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-2004
Корейский: cp949, euc-kr, johab, iso-2022-kr
Добавлены некоторые другие новые кодировки: HP Roman8, ISO_8859-11, ISO_8859-16, PCTP-154 и TIS-620.
Кодеки UTF-8 и UTF-16 теперь лучше справляются с приемом частичного ввода. Ранее класс
StreamReader
пытался прочитать больше данных, что делало невозможным возобновление декодирования из потока. Методread()
теперь будет возвращать как можно больше данных, а будущие вызовы возобновят декодирование с того места, где остановились предыдущие. (Реализовано Вальтером Дёрвальдом.)Существует новый модуль
collections
для различных специализированных типов данных коллекций. В настоящее время он содержит только один тип,deque
, двустороннюю очередь, которая поддерживает эффективное добавление и удаление элементов с любого конца:>>> from collections import deque >>> d = deque('ghi') # сделать новую deque с тремя элементами >>> d.append('j') # добавить новую запись в правую сторону >>> d.appendleft('f') # добавить новую запись слева >>> d # показать представление deque deque(['f', 'g', 'h', 'i', 'j']) >>> d.pop() # возвращает и удаляет крайний правый элемент 'j' >>> d.popleft() # вернуть и удалить крайний левый элемент 'f' >>> list(d) # перечислить содержимое deque ['g', 'h', 'i'] >>> 'h' in d # искать в deque True
Некоторые модули, такие как модули
Queue
иthreading
, теперь используютcollections.deque
для повышения производительности. (Предоставлено Рэймондом Хеттингером.)Классы
ConfigParser
были немного улучшены. Методread()
теперь возвращает список файлов, которые были успешно проанализированы, а методset()
возвращаетTypeError
, если передаётся аргумент value, который не является строкой. (Предоставлено Джоном Бельмонте и Дэвидом Гуджером.)Модуль
curses
теперь поддерживает расширение ncursesuse_default_colors()
. На платформах, где терминал поддерживает прозрачность, это позволяет использовать прозрачный фон. (Предоставлено Йоргом Леманном.)Модуль
difflib
теперь включает классHtmlDiff
, который создаёт HTML-таблицу, показывающую параллельное сравнение двух версий текста. (Предоставлено Дэном Гассом.)Пакет
email
был обновлен до версии 3.0, в которой удалены различные устаревшие API и удалена поддержка версий Python до 2.3. Версия пакета 3.0 использует новый добавочный парсер для сообщений MIME, доступный в модулеemail.FeedParser
. Новый синтаксический анализатор не требует считывания всего сообщения в память и не создаёт исключений, если сообщение искажено; вместо этого он записывает любые проблемы в атрибут сообщенияdefect
. (Разработано Энтони Бакстером, Барри Варшавой, Томасом Воутерсом и др.)Модуль
heapq
был преобразован в C. В результате десятикратное увеличение скорости делает модуль пригодным для обработки больших объемов данных. Кроме того, модуль имеет две новые функцииnlargest()
иnsmallest()
, которые используют кучи для поиска N самых больших или самых маленьких значений в множестве данных без затрат на полную сортировку. (Предоставлено Рэймондом Хеттингером.)Модуль
httplib
теперь содержит константы для кодов состояния HTTP, определённые в различных документах RFC, связанных с HTTP. Константы имеют такие имена, какOK
,CREATED
,CONTINUE
иMOVED_PERMANENTLY
; используйте pydoc, чтобы получить полный список. (Предоставлено Эндрю Эландом.)Модуль
imaplib
теперь поддерживает команду IMAP THREAD (предоставленную Yves Dionne) и новые методыdeleteacl()
иmyrights()
(предоставленную Арно Мазин).Модуль
itertools
получил функциюgroupby(iterable[, *func*])
. iterable — это то, что можно повторить, чтобы возвращает поток элементов, а необязательный параметр func — это функция, которая принимает элемент и возвращает значение ключа; если он пропущен, ключ является просто самим элементом. Затемgroupby()
группирует элементы в подпоследовательности, которые имеют совпадающие значения ключа, и возвращает серию из двух кортежей, содержащих значение ключа и итератор по подпоследовательности.Вот пример, чтобы сделать это более ясным. Функция key просто возвращает, является ли число четным или нечетным, поэтому результат
groupby()
должен возвращать последовательные серии нечетных или четных чисел.>>> import itertools >>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14] >>> for key_val, it in itertools.groupby(L, lambda x: x % 2): ... print key_val, list(it) ... 0 [2, 4, 6] 1 [7] 0 [8] 1 [9, 11] 0 [12, 14] >>>
groupby()
обычно используется с отсортированным вводом. Логика дляgroupby()
аналогична фильтру Unixuniq
, что делает его удобным для удаления, подсчета или идентификации повторяющихся элементов:>>> word = 'abracadabra' >>> letters = sorted(word) # Превратить строку в отсортированный список букв >>> letters ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r'] >>> for k, g in itertools.groupby(letters): ... print k, list(g) ... a ['a', 'a', 'a', 'a', 'a'] b ['b', 'b'] c ['c'] d ['d'] r ['r', 'r'] >>> # Список уникальных букв >>> [k for k, g in groupby(letters)] ['a', 'b', 'c', 'd', 'r'] >>> # Подсчет вхождений букв >>> [(k, len(list(g))) for k, g in groupby(letters)] [('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]
(Предоставил Хе-Шик Чанг.)
itertools
также получил функцию с именемtee(iterator, N)
, которая возвращает независимые итераторы N, которые копируют iterator. Если N пропущен, по умолчанию используется значение 2.>>> L = [1,2,3] >>> i1, i2 = itertools.tee(L) >>> i1,i2 (<itertools.tee object at 0x402c2080>, <itertools.tee object at 0x402c2090>) >>> list(i1) # Запустить первый итератор до завершения [1, 2, 3] >>> list(i2) # Запустить второй итератор до завершения [1, 2, 3]
Обратите внимание, что
tee()
должен хранить копии значений, возвращаемых итератором; в худшем случае может потребоваться сохранить их все. Поэтому его следует использовать с осторожностью, если ведущий итератор может опережать замыкающий итератор в длинном потоке входных данных. Если расстояние большое, вы можете вместо этого использоватьlist()
. Когда итераторы тесно связаны друг с другом, идеально подходитtee()
. Возможные приложения включают закладки, работу с окнами или итераторы с опережением. (Предоставлено Рэймондом Хеттингером.)В модуль
locale
был добавлен ряд функций, таких какbind_textdomain_codeset()
для указания кодировки, и семейство функцийl*gettext()
, которые возвращают сообщения в выбранной кодировке. (Предоставлено Густаво Нимейером.)Некоторые ключевые аргументы были добавлены в функцию
basicConfig()
пакетаlogging
для упрощения настройки журнала. По умолчанию сообщения записываются в стандартную ошибку, но можно указать различные ключевые аргументы для записи в определённый файл, изменения формата ведения журнала или установки уровня ведения журнала. Например:import logging logging.basicConfig(filename='/var/log/application.log', level=0, # Log all messages format='%(levelname):%(process):%(thread):%(message)')
Другие дополнения к пакету
logging
включают вспомогательный методlog(level, msg)
, а также классTimedRotatingFileHandler
, который меняет файлы журналов с заданным интервалом. Модуль уже имелRotatingFileHandler
, который сменял журналы, когда файл превышал определённый размер. Оба класса являются производными от нового классаBaseRotatingHandler
, который можно использовать для реализации других обработчиков ротации.(Изменения внес Винай Саджип.)
Модуль
marshal
теперь совместно использует интернированные строки при распаковке структуры данных. Может уменьшить размер некоторых пикл строк, но основной эффект заключается в значительном уменьшении размера файлов.pyc
. (Предоставлено Мартином фон Лёвисом)Класс
NNTP
модуляnntplib
получил методыdescription()
иdescriptions()
для получения описаний групп новостей для одной группы или для диапазона групп. (Предоставлено Юргеном А. Эрхардом)В модуль
operator
добавлены две новые функции:attrgetter(attr)
иitemgetter(index)
. Обе функции возвращают вызываемые объекты, которые принимают один аргумент и возвращают соответствующий атрибут или элемент; данные вызываемые объекты отлично подходят для извлечения данных при использовании сmap()
илиsorted()
. Например:>>> L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)] >>> map(operator.itemgetter(0), L) ['c', 'd', 'a', 'b'] >>> map(operator.itemgetter(1), L) [2, 1, 4, 3] >>> sorted(L, key=operator.itemgetter(1)) # Сортировка списка по второму элементу кортежа [('d', 1), ('c', 2), ('b', 3), ('a', 4)]
(Предоставлено Рэймондом Хеттингером.)
Модуль
optparse
обновлялся разными способами. Теперь модуль передает свои сообщения черезgettext.gettext()
, что позволяет интернационализировать справку и сообщения об ошибках Optik. Справочные сообщения для параметров теперь могут включать строку'%default'
, которая будет заменена значением параметра по умолчанию. (Предоставлено Грегом Уордом.)Долгосрочный план состоит в том, чтобы отказаться от модуля
rfc822
в одном из будущих релизов Python в пользу пакетаemail
. С этой целью функцияemail.Utils.formatdate()
была изменена, чтобы её можно было использовать в качестве заменыrfc822.formatdate()
. Возможно, вы захотите написать новый код обработки электронной почты с учётом этого. (Изменение внес Энтони Бакстер.)В модуль
os
добавлена новая функцияurandom(n)
, возвращающая строку, содержащую n байт случайных данных. Данная функция обеспечивает доступ к зависящим от платформы источникам случайности, таким как/dev/urandom
в Linux или Windows CryptoAPI. (Предоставлено Тревором Перрином.)Ещё одна новая функция:
os.path.lexists(path)
возвращает истина, если файл, указанный path, существует, независимо от того, является ли он символической ссылкой. Это отличается от существующей функцииos.path.exists(path)
, которая возвращает ложь, если path является символической ссылкой, указывающей на место назначения, которое не существует. (Предоставил Бени Чернявский.)В модуль
posix
, лежащий в основе модуляos
, добавлена новая функцияgetsid()
. (Предоставлено Дж. Рейнором.)Модуль
poplib
теперь поддерживает POP через SSL. (Предоставлено Гектором Уртубиа.)Модуль
profile
теперь может профилировать функции расширения C. (Предоставлено Ником Бастином.)Модуль
random
имеет новый методgetrandbits(N)
, который возвращает длинное целое число N битов. Существующий методrandrange()
теперь при необходимости используетgetrandbits()
, что делает генерацию произвольно больших случайных чисел более эффективной. (Предоставлено Рэймондом Хеттингером.)Язык регулярных выражений, принятый модулем
re
, был расширен простыми условными выражениями, записанными как(?(group)A|B)
. group — это либо числовой идентификатор группы, либо имя группы, определенное с помощью(?P<group>...)
ранее в выражении. Если указанная группа совпала, шаблон регулярного выражения A будет проверен на соответствие строке; если группа не совпала, вместо нее будет использоваться шаблон B. (Предоставлено Густаво Нимейером.)Модуль
re
также больше не является рекурсивным благодаря огромной работе Густаво Нимейера. В рекурсивном механизме регулярных выражений определённые шаблоны приводят к потреблению большого объема пространства стека C, и стек может быть переполнен. Например, если вы сопоставили 30000-байтовую строку символовa
с выражением(a|b)+
, для каждого символа использовался один фрейм стека. Python 2.3 попытался проверить переполнение стека и вызвать исключениеRuntimeError
, но некоторые шаблоны могли обойти проверку, и, если вам не повезло, Python мог segfault. Механизм регулярных выражений Python 2.4 может без проблем сопоставить данный шаблон.Модуль
signal
теперь выполняет более тщательную проверку на ошибки параметров функцииsignal.signal()
. Например, вы не можете установить обработчик сигналаSIGKILL
; предыдущие версии Python спокойно приняли бы это, но 2.4 вызовет исключениеRuntimeError
.В модуль
socket
добавлены две новые функции.socketpair()
возвращает пару подключенных сокетов, аgetservbyport(port)
ищет имя службы для заданного номера порта. (Предоставлено Дэйвом Коулом и Барри Варшавой.)Функция
sys.exitfunc()
устарела. Код должен использовать существующий модульatexit
, который правильно обрабатывает вызов нескольких функций выхода. Со временемsys.exitfunc()
станет чисто внутренним интерфейсом, доступ к которому будет иметь толькоatexit
.Модуль
tarfile
теперь по умолчанию генерирует tar-файлы в формате GNU. (Предоставлено Ларсом Густебелем.)Модуль
threading
теперь имеет элегантный простой способ поддержки локальных данных потока. Модуль содержит классlocal
, значения атрибутов которого являются локальными для разных потоков.import threading data = threading.local() data.number = 42 data.url = ('www.python.org', 80)
Другие потоки могут назначать и извлекать собственные значения атрибутов
number
иurl
. Вы можете создать подклассlocal
для инициализации атрибутов или добавления методов. (Предоставлено Джимом Фултоном.)Модуль
timeit
теперь автоматически отключает периодическую сборку мусора во время временного цикла. Это изменение делает последовательные тайминги более сопоставимыми. (Предоставлено Рэймондом Хеттингером.)Модуль
weakref
теперь поддерживает более широкий спектр объектов, включая функции Python, экземпляры классов, наборы, замороженные наборы, очереди, массивы, файлы, сокеты и объекты шаблонов регулярных выражений. (Предоставлено Рэймондом Хеттингером.)Модуль
xmlrpclib
теперь поддерживает расширение с несколькими вызовами для передачи нескольких вызовов XML-RPC в одной операции HTTP. (Предоставлено Брайаном Куинланом.)Модули
mpz
,rotor
иxreadlines
удалены.
cookielib¶
Библиотека cookielib
поддерживает обработку cookie HTTP на стороне
клиента, отражая поддержку cookie на стороне сервера модулем Cookie
.
Cookie хранятся в банках для cookie; библиотека прозрачно хранит cookie,
предлагаемые веб-сервером, в банке cookie и извлекает cookie из банки при
подключении к серверу. Как и в веб-браузерах, объекты политики определяют,
принимаются ли cookie или нет.
Для хранения cookie между сеансами предоставляются две реализации cookie: одна хранит cookie в формате Netscape, чтобы приложения могли использовать cookie Mozilla или Lynx, а другая хранит cookie в том же формате, что и библиотека Perl libwww.
urllib2
был изменён для взаимодействия с cookielib
:
HTTPCookieProcessor
управляет файлом cookie, который используется при
доступе к URL-адресам.
Данный модуль был предоставлен Джоном Дж. Ли.
doctest¶
Модуль doctest
подвергся значительному рефакторингу благодаря Эдварду
Лоперу и Тиму Питерсу. Тестирование по-прежнему может быть таким же простым,
как запуск doctest.testmod()
, но рефакторинг позволяет настроить работу
модуля различными способами
Новый класс DocTestFinder
извлекает тесты из строк документации
данного объекта:
def f (x, y):
""">>> f(2,2)
4
>>> f(3,2)
6
"""
return x*y
finder = doctest.DocTestFinder()
# Получить список экземпляров DocTest
tests = finder.find(f)
Затем новый класс DocTestRunner
запускает отдельные тесты и может
выводить сводку результатов:
runner = doctest.DocTestRunner()
for t in tests:
tried, failed = runner.run(t)
runner.summarize(verbose=1)
В приведённом выше примере выводится следующий результат:
1 items passed all tests:
2 tests in f
2 tests in 1 items.
2 passed and 0 failed.
Test passed.
DocTestRunner
использует экземпляр класса OutputChecker
для
сравнения ожидаемого вывода с фактическим. Данный класс принимает ряд различных
флагов, которые настраивают его поведение; амбициозные пользователи также могут
написать совершенно новый подкласс OutputChecker
.
Средство проверки вывода по умолчанию предоставляет ряд удобных функций.
Например, с флагом параметра doctest.ELLIPSIS
многоточие (...
) в
ожидаемых выходных данных соответствует любой подстроке, что упрощает
согласование выходных данных, которые незначительно различаются:
def o (n):
""">>> o(1)
<__main__.C instance at 0x...>
>>>
"""
Другая специальная строка, <BLANKLINE>
, соответствует пустой строке:
def p (n):
""">>> p(1)
<BLANKLINE>
>>>
"""
Ещё одна новая возможность заключается в отображении выходных данных в стиле
различий путём указания флагов опций doctest.REPORT_UDIFF
(унифицированные различия), doctest.REPORT_CDIFF
(контекстные
различия) или doctest.REPORT_NDIFF
(дельта-стиль). Например:
def g (n):
""">>> g(4)
here
is
a
lengthy
>>>"""
L = 'here is a rather lengthy list of words'.split()
for word in L[:n]:
print word
Выполнив приведенные выше тесты функции с указанным
doctest.REPORT_UDIFF
, вы получить следующий вывод:
**********************************************************************
File "t.py", line 15, in g
Failed example:
g(4)
Differences (unified diff with -expected +actual):
@@ -2,3 +2,3 @@
is
a
-lengthy
+rather
**********************************************************************
Изменения сборки и C API¶
Вот некоторые изменения в процессе сборки Python и C API:
Добавлены три новых удобных макроса для распространенных значений, возвращаемых функциями расширения:
Py_RETURN_NONE
,Py_RETURN_TRUE
иPy_RETURN_FALSE
. (Предоставлено Бреттом Кэнноном.)Другой новый макрос,
Py_CLEAR(obj)
, уменьшает счётчик ссылок obj и устанавливает obj в нулевой указатель. (Предоставлено Джимом Фултоном)Новая функция
PyTuple_Pack(N, obj1, obj2, ..., objN)
создаёт кортежи из списка аргументов переменной длины объектов Python. (Предоставлено Рэймондом Хеттингером.)Новая функция
PyDict_Contains(d, k)
реализует быстрый поиск по словарю без маскирования исключений, возникающих в процессе поиска. (Предоставлено Рэймондом Хеттингером.)Макрос
Py_IS_NAN(X)
возвращает 1, если его аргумент float или double X является NaN. (Предоставлено Тимом Питерсом.)Код C может избежать ненужной блокировки, используя новую функцию
PyEval_ThreadsInitialized()
, чтобы узнать, были ли выполнены какие- либо операции потока. Если данная функция возвращает ложь, операции блокировки не требуются. (Предоставлено Ником Когланом.)Новая функция,
PyArg_VaParseTupleAndKeywords()
, аналогичнаPyArg_ParseTupleAndKeywords()
, но принимаетva_list
вместо ряда аргументов. (Предоставлено Грегом Чепменом.)Новый флаг метода
METH_COEXISTS
позволяет функции, определенной в слотах, сосуществовать сPyCFunction
с тем же именем. Это может вдвое сократить время доступа для такого метода, какset.__contains__()
. (Предоставлено Рэймондом Хеттингером.)Теперь Python можно создавать с дополнительным профилированием самого интерпретатора, предназначенным для помощи людям, разрабатывающим ядро Python. Предоставление
--enable-profiling
сценарию configure позволит вам профилировать интерпретатор с помощью gprof, а предоставление переключателя--with-tsc
позволяет профилировать с использованием регистра Pentium-Time-Stamp-Counter. Обратите внимание, что имя опции--with-tsc
немного неверно, потому что функция профилирования также работает на платформе PowerPC, хотя в этой архитектуре процессора данный регистр не называется «регистром TSC». (Предоставлено Джереми Хилтоном)Тип
tracebackobject
был переименован вPyTracebackObject
.
Изменения для порта¶
- Перенос для Windows теперь строится под MSVC++ 7.1, а также под версию 6. (Предоставлено Мартином фон Лёвисом.)
Портирование на Python 2.4¶
В этом разделе перечислены ранее описанные изменения, которые могут потребовать внесения изменений в ваш код:
- Слишком большие сдвиги влево и шестнадцатеричные/восьмеричные константы
больше не вызывают
FutureWarning
и возвращают значение, ограниченное 32 или 64 битами; вместо этого они возвращают длинное целое число. - Целочисленные операции больше не будут вызывать ошибку
OverflowWarning
. ПредупреждениеOverflowWarning
исчезнет в Python 2.5. - Встроенная функция
zip()
иitertools.izip()
теперь возвращают пустой список, а не вызывают исключениеTypeError
, если вызываются без аргументов. - Вы больше не можете сравнивать экземпляры
date
иdatetime
, предоставляемые модулемdatetime
. Два экземпляра разных классов теперь всегда будут неравны, а относительные сравнения (<
,>
) будут вызыватьTypeError
. dircache.listdir()
теперь передает исключения вызывающему объекту вместо возврата пустых списков.LexicalHandler.startDTD()
используется для получения общедоступных и системных идентификаторов в неправильном порядке. Это было исправлено; приложения, полагающиеся на неправильный порядок, должны быть исправлены.fcntl.ioctl()
теперь предупреждает, если аргумент mutate пропущен и актуален.- Модуль
tarfile
теперь по умолчанию генерирует tar-файлы в формате GNU. - Сбой при импорте модуля больше не оставляет частично инициализированный
объект модуля в
sys.modules
. None
теперь является константой; код, связывающий новое значение с именемNone
, теперь является синтаксической ошибкой.- Функция
signals.signal()
теперь вызывает исключениеRuntimeError
для определенных недопустимых значений; раньше данные ошибки проходили бы молча. Например, вы больше не можете установить обработчик сигналаSIGKILL
.
Благодарности¶
Автор хотел бы поблагодарить следующих людей за предложения, исправления и помощь с различными черновиками этой статьи: Корай Кан, Хе-Шик Чанг, Майкл Дайк, Рэймонд Хеттингер, Брайан Хёрт, Хэмиш Лоусон, Фредрик Лунд, Шон Рейфшнайдер, Садруддин. Реджеб.