Що нового в Python 2.3

Автор:

A.M. Kuchling

У цій статті пояснюються нові функції Python 2.3. Python 2.3 був випущений 29 липня 2003 року.

Основними темами для Python 2.3 є вдосконалення деяких функцій, доданих у 2.2, додавання різних невеликих, але корисних покращень до основної мови та розширення стандартної бібліотеки. Нова об’єктна модель, представлена в попередній версії, отримала переваги від 18 місяців виправлення помилок і зусиль з оптимізації, які покращили продуктивність класів нового стилю. Було додано кілька нових вбудованих функцій, таких як sum() і enumerate(). Оператор in тепер можна використовувати для пошуку підрядка (наприклад, "ab" у "abc" повертає True).

Деякі з багатьох нових функцій бібліотеки включають типи даних Boolean, set, heap і date/time, можливість імпортувати модулі з архівів у форматі ZIP, підтримку метаданих для довгоочікуваного каталогу Python, оновлену версію IDLE та модулі. для реєстрації повідомлень, обтікання текстом, аналізу файлів CSV, обробки параметрів командного рядка, використання баз даних BerkeleyDB… список нових і вдосконалених модулів довгий.

Ця стаття не намагається надати повну специфікацію нових функцій, натомість надає зручний огляд. Щоб отримати повну інформацію, зверніться до документації для Python 2.3, такої як Довідник бібліотеки Python і Довідковий посібник Python. Якщо ви хочете зрозуміти повну реалізацію та обґрунтування дизайну, зверніться до PEP для конкретної нової функції.

PEP 218: Тип даних стандартного набору

The new sets module contains an implementation of a set datatype. The Set class is for mutable sets, sets that can have members added and removed. The ImmutableSet class is for sets that can’t be modified, and instances of ImmutableSet can therefore be used as dictionary keys. Sets are built on top of dictionaries, so the elements within a set must be hashable.

Ось простий приклад:

>>> 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])
>>>

The union and intersection of sets can be computed with the union() and intersection() methods; an alternative notation uses the bitwise operators & and |. Mutable sets also have in-place versions of these methods, union_update() and 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                  # Alternative notation
Set([1, 2, 3, 4, 5, 6])
>>> S1.intersection(S2)
Set([])
>>> S1 & S2                  # Alternative notation
Set([])
>>> S1.union_update(S2)
>>> S1
Set([1, 2, 3, 4, 5, 6])
>>>

It’s also possible to take the symmetric difference of two sets. This is the set of all elements in the union that aren’t in the intersection. Another way of putting it is that the symmetric difference contains all elements that are in exactly one set. Again, there’s an alternative notation (^), and an in-place version with the ungainly name 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])
>>>

There are also issubset() and issuperset() methods for checking whether one set is a subset or superset of another:

>>> 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 - Додавання вбудованого типу об’єкта Set

PEP, написаний Грегом В. Вілсоном. Реалізовано Грегом В. Вілсоном, Алексом Мартеллі та GvR.

PEP 255: Прості генератори

У Python 2.2 генератори були додані як необов’язкова функція, яка вмикається директивою from __future__ import generators. У версії 2.3 генератори більше не потребують спеціального вмикання, і тепер вони завжди присутні; це означає, що yield тепер завжди є ключовим словом. Решта цього розділу є копією опису генераторів із документа «Що нового в 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 оператора tryfinally; читайте PEP 255 для повного пояснення взаємодії між yield і винятками.)

Here’s a sample usage of the generate_ints() generator:

>>> 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 містить ще кілька цікавих прикладів. Найпростіший реалізує рекурсивний обхід дерева за допомогою генераторів.

# A recursive generator that generates Tree leaves in 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-Queens (розміщення $N$ ферзів на $NxN$ шахівниці так, щоб жодна королева не загрожувала іншій) і Knight’s Tour (a маршрут, який веде лицаря до кожного поля $NxN$ шахівниці, не відвідуючи жодного поля двічі).

The idea of generators comes from other programming languages, especially Icon (https://www2.cs.arizona.edu/icon/), where the idea of generators is central. In Icon, every expression and function call behaves like a generator. One example from «An Overview of the Icon Programming Language» at https://www2.cs.arizona.edu/icon/docs/ipd266.htm gives an idea of what this looks like:

sentence := "Store it in the neighboring harbor"
if (i := find("or", sentence)) > 5 then write(i)

In Icon the find() function returns the indexes at which the substring «or» is found: 3, 23, 33. In the if statement, i is first assigned a value of 3, but 3 is less than 5, so the comparison fails, and Icon retries it with the second value of 23. 23 is greater than 5, so the comparison now succeeds, and the code prints the value 23 to the screen.

Python не заходить так далеко, як Icon, у прийнятті генераторів як центральної концепції. Генератори вважаються частиною основної мови Python, але їх вивчення або використання не є обов’язковим; якщо вони не вирішують жодних ваших проблем, не соромтеся їх ігнорувати. Однією з нових особливостей інтерфейсу Python порівняно з інтерфейсом Icon є те, що стан генератора представлено як конкретний об’єкт (ітератор), який можна передати іншим функціям або зберегти в структурі даних.

Дивись також

PEP 255 - Прості генератори

Автори: Ніл Шеменауер, Тім Пітерс, Магнус Лі Хетленд. Реалізовано переважно Нілом Шеменауером і Тімом Пітерсом, інші виправлення внесені командою Python Labs.

PEP 263: Кодування вихідного коду

Вихідні файли 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

Автори: Марк-Андре Лембург і Мартін фон Льовіс; реалізовано Сузукі Хісао та Мартіном фон Льовісом.

PEP 273: Імпортування модулів із ZIP-архівів

Новий модуль 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-архівів

Написав Джеймс К. Алстром, який також забезпечив реалізацію. Python 2.3 відповідає специфікації в PEP 273, але використовує реалізацію, написану Джастом ван Россумом, яка використовує хуки імпорту, описані в PEP 302. Перегляньте розділ PEP 302: нові імпортні гачки для опису нових хуків імпорту.

PEP 277: Підтримка імен файлів Unicode для Windows NT

У Windows NT, 2000 і XP система зберігає імена файлів як рядки Unicode. Традиційно Python представляє імена файлів у вигляді байтових рядків, що є неадекватним, оскільки робить деякі імена файлів недоступними.

Python now allows using arbitrary Unicode strings (within the limitations of the file system) for all functions that expect file names, most notably the open() built-in function. If a Unicode string is passed to os.listdir(), Python now returns a list of Unicode strings. A new function, os.getcwdu(), returns the current directory as a Unicode string.

Байтові рядки все ще працюють як імена файлів, і в Windows Python прозоро перетворює їх у Unicode за допомогою кодування mbcs.

Інші системи також дозволяють рядки Unicode як імена файлів, але перетворюють їх на рядки байтів перед передачею в систему, що може спричинити виникнення UnicodeError. Програми можуть перевірити, чи підтримуються довільні рядки Unicode як імена файлів, перевіривши os.path.supports_unicode_filenames, логічне значення.

У MacOS os.listdir() тепер може повертати імена файлів у кодуванні Unicode.

Дивись також

PEP 277 - Підтримка імен файлів Unicode для Windows NT

Автор Ніл Ходжсон; реалізований Нілом Ходжсоном, Мартіном фон Льовісом і Марком Хаммондом.

PEP 278: універсальна підтримка нового рядка

Сьогодні використовуються три основні операційні системи: Microsoft Windows, Macintosh OS від Apple і різні похідні Unix. Невелике роздратування кросплатформної роботи полягає в тому, що всі ці три платформи використовують різні символи для позначення кінців рядків у текстових файлах. Unix використовує символ переводу рядка (символ ASCII 10), MacOS використовує символ повернення каретки (символ ASCII 13), а Windows використовує двосимвольну послідовність повернення каретки плюс новий рядок.

Python’s file objects can now support end of line conventions other than the one followed by the platform on which Python is running. Opening a file with the mode 'U' or 'rU' will open a file for reading in universal newlines mode. All three line ending conventions will be translated to a '\n' in the strings returned by the various file methods such as read() and readline().

Universal newline support is also used when importing modules and when executing a file with the execfile() function. This means that Python modules can be shared between all three operating systems without needing to convert the line-endings.

Цю функцію можна вимкнути під час компіляції Python, вказавши параметр --without-universal-newlines під час виконання сценарію configure Python.

Дивись також

PEP 278 - Універсальна підтримка нового рядка

Написаний і реалізований Джеком Янсеном.

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]
    # ... compute some result based on item ...
    L[i] = result

Це можна переписати за допомогою enumerate() як:

for i, item in enumerate(L):
    # ... compute some result based on item ...
    L[i] = result

Дивись також

PEP 279 - Вбудована функція enumerate().

Написаний і реалізований Реймондом Д. Хеттінгером.

PEP 282: пакет журналів

Стандартний пакет для запису журналів, logging, було додано до Python 2.3. Він забезпечує потужний і гнучкий механізм для генерації результатів журналювання, які потім можна фільтрувати та обробляти різними способами. Файл конфігурації, написаний у стандартному форматі, можна використовувати для керування поведінкою програми в журналі. Python включає обробники, які записуватимуть записи журналу до стандартної помилки або до файлу чи сокета, надсилатимуть їх до системного журналу чи навіть електронною поштою на певну адресу; звичайно, також можна написати власні класи обробників.

The Logger class is the primary class. Most application code will deal with one or more Logger objects, each one used by a particular subsystem of the application. Each Logger is identified by a name, and names are organized into a hierarchy using . as the component separator. For example, you might have Logger instances named server, server.auth and server.network. The latter two instances are below server in the hierarchy. This means that if you turn up the verbosity for server or direct server messages to a different handler, the changes will also apply to records logged to server.auth and server.network. There’s also a root Logger that’s the parent of all other loggers.

Для простого використання пакет 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

In the default configuration, informational and debugging messages are suppressed and the output is sent to standard error. You can enable the display of informational and debugging messages by calling the setLevel() method on the root logger.

Notice the warning() call’s use of string formatting operators; all of the functions for logging messages take the arguments (msg, arg1, arg2, ...) and log the string resulting from msg % (arg1, arg2, ...).

There’s also an exception() function that records the most recent traceback. Any of the other functions will also record the traceback if you specify a true value for the keyword argument 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')
 ...

Log records are usually propagated up the hierarchy, so a message logged to server.auth is also seen by server and root, but a Logger can prevent this by setting its propagate attribute to False.

There are more classes provided by the logging package that can be customized. When a Logger instance is told to log a message, it creates a LogRecord instance that is sent to any number of different Handler instances. Loggers and handlers can also have an attached list of filters, and each filter can cause the LogRecord to be ignored or can modify the record before passing it along. When they’re finally output, LogRecord instances are converted to text by a Formatter class. All of these classes can be replaced by your own specially written classes.

З усіма цими функціями пакет logging має забезпечити достатню гнучкість навіть для найскладніших програм. Це лише неповний огляд його функцій, тому, будь ласка, перегляньте довідкову документацію пакета, щоб отримати всі деталі. Читання PEP 282 також буде корисним.

Дивись також

PEP 282 - Система реєстрації

Автори: Віней Саджип і Трент Мік; реалізовано Вінаєм Саджипом.

PEP 285: логічний тип

A Boolean type was added to Python 2.3. Two new constants were added to the __builtin__ module, True and False. (True and False constants were added to the built-ins in Python 2.2.1, but the 2.2.1 versions are simply set to integer values of 1 and 0 and aren’t a different type.)

Об’єкт типу для цього нового типу називається 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 були додані з головною метою зробити код зрозумілішим. Наприклад, якщо ви читаєте функцію та зустрічаєте оператор повернути 1, ви можете запитати, чи 1 представляє логічне значення істинності, індекс або коефіцієнт, який множить якусь іншу величину. Однак, якщо оператор повернути Істину, значення значення, що повертається, цілком зрозуміле.

Логічні значення Python не додано задля суворої перевірки типу. Дуже сувора мова, така як Паскаль, також завадить вам виконувати арифметику з булевими значеннями, і вимагатиме, щоб вираз у операторі 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 - Додавання типу bool

Написано та реалізовано GvR.

PEP 293: Зворотні виклики обробки помилок кодека

Під час кодування рядка Юнікод у рядок байтів можуть зустрітися некодовані символи. Наразі Python дозволяв вказувати обробку помилок як «строгу» (викликаючи UnicodeError), «ігнорувати» (пропускаючи символ) або «замінювати» (використовуючи знак питання у вихідному рядку), з «суворий» є поведінкою за замовчуванням. Може бути бажано вказати альтернативну обробку таких помилок, таку як вставка посилання на символ XML або посилання на сутність HTML у перетворений рядок.

Python тепер має гнучку структуру для додавання різних стратегій обробки. Нові обробники помилок можна додати за допомогою codecs.register_error(), а потім кодеки зможуть отримати доступ до обробника помилок за допомогою codecs.lookup_error(). Для кодеків, написаних мовою C, додано еквівалентний C API. Обробник помилок отримує необхідну інформацію про стан, таку як рядок, який перетворюється, позиція в рядку, де було виявлено помилку, і цільове кодування. Тоді обробник може викликати виняток або повернути рядок заміни.

За допомогою цього фреймворку було реалізовано два додаткові обробники помилок: «backslashreplace» використовує лапки Python для представлення некодованих символів, а «xmlcharrefreplace» видає посилання на символи XML.

Дивись також

PEP 293 - Помилка кодека при обробці зворотних викликів

Написав і реалізував Вальтер Дьорвальд.

PEP 301: Індекс пакетів і метадані для Distutils

Підтримка давно запитуваного каталогу Python вперше з’являється у 2.3.

Серцем каталогу є нова команда Distutils register. Запуск python setup.py register збирає метадані, що описують пакунок, наприклад його назву, версію, супроводжуючого, опис тощо, і надсилає їх на центральний сервер каталогу. Отриманий каталог доступний за адресою https://pypi.org.

To make the catalog a bit more useful, a new optional classifiers keyword argument has been added to the Distutils setup() function. A list of Trove-style strings can be supplied to help classify the software.

Ось приклад 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

Написаний і реалізований Річардом Джонсом.

PEP 302: нові імпортні гачки

While it’s been possible to write custom import hooks ever since the ihooks module was introduced in Python 1.3, no one has ever been really happy with it because writing new import hooks is difficult and messy. There have been various proposed alternatives such as the imputil and iu modules, but none of them has ever gained much acceptance, and none of them were easily usable from C code.

PEP 302 borrows ideas from its predecessors, especially from Gordon McMillan’s iu module. Three new items are added to the sys module:

  • sys.path_hooks - це список викликаних об’єктів; найчастіше це будуть класи. Кожен виклик приймає рядок, що містить шлях, і або повертає об’єкт імпортера, який оброблятиме імпорт із цього шляху, або викликає виняток ImportError, якщо він не може обробити цей шлях.

  • sys.path_importer_cache кешує об’єкти імпортера для кожного шляху, тому sys.path_hooks потрібно буде пройти лише один раз для кожного шляху.

  • sys.meta_path - це список об’єктів імпортера, які будуть проходити перед перевіркою sys.path. Спочатку цей список порожній, але код користувача може додавати до нього об’єкти. Додаткові вбудовані та заморожені модулі можуть бути імпортовані об’єктом, доданим до цього списку.

Importer objects must have a single method, find_module(fullname, path=None). fullname will be a module or package name, e.g. string or distutils.core. find_module() must return a loader object that has a single method, load_module(fullname), that creates and returns the corresponding module object.

Таким чином, псевдокод для нової логіки імпорту 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, so try the other path hooks
            pass
        else:
            loader = importer.find_module(fullname)
            <module> = loader.load_module(fullname)

# Not found!
raise ImportError

Дивись також

PEP 302 - Нові хуки імпорту

Автори: Джаст ван Россум і Пол Мур. Реалізовано Юстом ван Россумом.

PEP 305: Файли, розділені комами

Файли, розділені комами, — це формат, який часто використовується для експорту даних із баз даних і електронних таблиць. 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

The reader() function takes a number of different options. The field separator isn’t limited to the comma and can be changed to any character, and so can the quoting and line-ending characters.

Можна визначати та реєструвати різні діалекти файлів, розділених комами; наразі існує два діалекти, обидва використовуються Microsoft Excel. Окремий клас csv.writer генеруватиме файли, розділені комами, із послідовності кортежів або списків, цитуючи рядки, які містять роздільник.

Дивись також

PEP 305 - API файлів CSV

Написали та реалізували Кевін Алтіс, Дейв Коул, Ендрю Макнамара, Скіп Монтанаро, Кліфф Веллс.

PEP 307: Поліпшення соління

The pickle and cPickle modules received some attention during the 2.3 development cycle. In 2.2, new-style classes could be pickled without difficulty, but they weren’t pickled very compactly; PEP 307 quotes a trivial example where a new-style class results in a pickled string three times longer than that for a classic class.

Вихід полягав у винаході нового протоколу маринування. Функція pickle.dumps() довгий час підтримувала текстовий або бінарний прапор. У версії 2.3 цей прапорець змінено з логічного значення на ціле: 0 — це старий текстовий формат pickle, 1 — старий двійковий формат, а тепер 2 — це новий формат, специфічний для 2.3. Нову константу, pickle.HIGHEST_PROTOCOL, можна використовувати для вибору найбільш модного доступного протоколу.

Unpickling is no longer considered a safe operation. 2.2’s pickle provided hooks for trying to prevent unsafe classes from being unpickled (specifically, a __safe_for_unpickling__ attribute), but none of this code was ever audited and therefore it’s all been ripped out in 2.3. You should not unpickle untrusted data in any version of 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.

Щоб ще більше стиснути pickles, тепер можна використовувати цілі коди замість довгих рядків для ідентифікації маринованих класів. Python Software Foundation підтримуватиме список стандартизованих кодів; також є ряд кодів для приватного використання. Наразі коди не вказано.

Дивись також

PEP 307 - Розширення протоколу pickle

Написано та реалізовано Гвідо ван Россумом і Тімом Пітерсом.

Розширені зрізи

Починаючи з Python 1.4, синтаксис нарізки підтримує додатковий третій аргумент «крок» або «крок». Наприклад, це законний синтаксис Python: L[1:10:2], L[:-1:1], L[::-1]. Це було додано до Python на прохання розробників Numerical Python, який широко використовує третій аргумент. Однак вбудовані типи списків, кортежів і послідовностей рядків Python ніколи не підтримували цю функцію, викликаючи TypeError, якщо ви спробували її. Майкл Хадсон вніс патч для усунення цього недоліку.

Наприклад, тепер ви можете легко витягти елементи списку, які мають парні індекси:

>>> 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)

З цього прикладу ви також можете побачити, що вбудований об’єкт slice тепер є об’єктом типу для типу зрізу, і більше не є функцією. Це узгоджується з Python 2.2, де int, str тощо зазнали тих самих змін.

Інші зміни мови

Ось усі зміни, внесені Python 2.3 до основної мови Python.

  • Оператор yield тепер завжди є ключовим словом, як описано в розділі PEP 255: Прості генератори цього документа.

  • Було додано нову вбудовану функцію enumerate(), як описано в розділі PEP 279: enumerate() цього документа.

  • Дві нові константи, True і False було додано разом із вбудованим типом bool, як описано в розділі PEP 285: логічний тип цього документа.

  • Конструктор типу int() тепер повертатиме довге ціле число замість того, щоб викликати OverflowError, коли рядок або число з плаваючою комою занадто велике, щоб поміститися в ціле число. Це може призвести до парадоксального результату, що isinstance(int(expression), int) є хибним, але це навряд чи викличе проблеми на практиці.

  • Вбудовані типи тепер підтримують розширений синтаксис нарізки, як описано в розділі Розширені зрізи цього документа.

  • Нова вбудована функція, sum(iterable, start=0), додає числові елементи в ітераційному об’єкті та повертає їхню суму. sum() приймає лише числа, тобто ви не можете використовувати його для об’єднання рядків. (Надав Алекс Мартеллі.)

  • list.insert(pos, value) використовувався для вставки value на початку списку, коли pos було від’ємним. Поведінку тепер змінено для узгодження з індексуванням фрагментів, тому, коли pos дорівнює -1, значення буде вставлено перед останнім елементом і так далі.

  • list.index(value), який шукає value у списку та повертає його індекс, тепер приймає додаткові аргументи start і stop, щоб обмежити пошук лише частиною списку.

  • У словниках є новий метод, pop(key[, *default*]), який повертає значення, що відповідає key, і видаляє цю пару ключ/значення зі словника. Якщо потрібний ключ відсутній у словнику, повертається default, якщо його вказано, і KeyError, якщо його немає.

    >>> 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
    {}
    >>>
    

    Існує також новий метод класу, dict.fromkeys(iterable, value), який створює словник із ключами, взятими з наданого ітератора iterable, і всіма значеннями, встановленими на value, за умовчанням None .

    (Патчі надав Раймонд Геттінгер.)

    Крім того, конструктор dict() тепер приймає аргументи ключових слів для спрощення створення невеликих словників:

    >>> dict(red=1, blue=2, green=3, black=4)
    {'blue': 2, 'black': 4, 'green': 3, 'red': 1}
    

    (Надав Джаст ван Россум.)

  • Оператор assert більше не перевіряє прапорець __debug__, тому ви більше не можете вимкнути твердження, призначивши __debug__. Запуск Python із перемикачем -O усе одно генеруватиме код, який не виконує жодних тверджень.

  • 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'
    
  • Було додано нове попередження PendingDeprecationWarning, щоб вказати на функції, які перебувають у процесі припинення підтримки. За замовчуванням попередження не друкуватиметься. Щоб перевірити використання функцій, які в майбутньому будуть припинені, укажіть -Walways::PendingDeprecationWarning:: у командному рядку або скористайтеся warnings.filterwarnings().

  • Процес припинення винятків на основі рядків, як у підвищення "Сталася помилка", розпочато. Підвищення рядка тепер ініціює PendingDeprecationWarning.

  • Використання None як назви змінної тепер призведе до попередження SyntaxWarning. У майбутній версії Python None може нарешті стати ключовим словом.

  • 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.

  • The method resolution order used by new-style classes has changed, though you’ll only notice the difference if you have a really complicated inheritance hierarchy. Classic classes are unaffected by this change. Python 2.2 originally used a topological sort of a class’s ancestors, but 2.3 now uses the C3 algorithm as described in the paper «A Monotonic Superclass Linearization for Dylan». To understand the motivation for this change, read Michele Simionato’s article The Python 2.3 Method Resolution Order, or read the thread on python-dev starting with the message at https://mail.python.org/pipermail/python-dev/2002-October/029035.html. Samuele Pedroni first pointed out the problem and also implemented the fix by coding the C3 algorithm.

  • 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'>
    
  • One of the noted incompatibilities between old- and new-style classes has been removed: you can now assign to the __name__ and __bases__ attributes of new-style classes. There are some restrictions on what can be assigned to __bases__ along the lines of those relating to assigning to an instance’s __class__ attribute.

Зміни рядків

  • Оператор in тепер працює інакше для рядків. Раніше під час обчислення X в Y, де X і Y є рядками, X міг бути лише одним символом. Тепер це змінилося; X може бути рядком будь-якої довжини, і X в Y поверне True, якщо X є підрядком Y. Якщо X є порожнім рядком, результат завжди буде 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'
    >>>
    

    (Запропоновано Саймоном Бруннінгом і реалізовано Вальтером Дорвальдом.)

  • 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'
    

    (Надав Вальтер Дьорвальд.)

  • 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.

  • Внутрішні рядки більше не є безсмертними і тепер збиратимуть сміття у звичайний спосіб, якщо єдине посилання на них міститься у внутрішньому словнику інтернованих рядків. (Реалізовано Ореном Тірошем.)

Оптимізації

  • Створення екземплярів класу нового стилю стало набагато швидшим; тепер вони швидше, ніж класичні заняття!

  • The sort() method of list objects has been extensively rewritten by Tim Peters, and the implementation is significantly faster.

  • Multiplication of large long integers is now much faster thanks to an implementation of Karatsuba multiplication, an algorithm that scales better than the O(n2) required for the grade-school multiplication algorithm. (Original patch by Christopher A. Craig, and significantly reworked by Tim Peters.)

  • Код операції SET_LINENO тепер зник. Це може забезпечити невелике збільшення швидкості, залежно від особливостей вашого компілятора. Перегляньте розділ Інші зміни та виправлення для більш детального пояснення. (Вилучено Майклом Хадсоном.)

  • xrange() objects now have their own iterator, making for i in xrange(n) slightly faster than for i in range(n). (Patch by Raymond Hettinger.)

  • У різних гарячих точках було зроблено ряд невеликих змін, щоб покращити продуктивність, як-от вбудовування функції або видалення деякого коду. (Реалізовано переважно GvR, але багато людей внесли окремі зміни.)

Кінцевим результатом оптимізації 2.3 є те, що Python 2.3 виконує тест pystone приблизно на 25% швидше, ніж Python 2.2.

Нові, покращені та застарілі модулі

Як завжди, стандартна бібліотека Python отримала низку вдосконалень і виправлень помилок. Ось неповний список найбільш помітних змін, відсортованих за алфавітом назв модулів. Зверніться до файлу Misc/NEWS у дереві вихідних кодів, щоб отримати більш повний список змін, або перегляньте журнали CVS, щоб отримати всі деталі.

  • Модуль array тепер підтримує масиви символів Unicode з використанням символу формату 'u'. Масиви також тепер підтримують використання оператора призначення += для додавання вмісту іншого масиву та оператора призначення *= для повторення масиву. (Надав Джейсон Орендорф.)

  • The bsddb module has been replaced by version 4.1.6 of the PyBSDDB package, providing a more complete interface to the transactional features of the BerkeleyDB library.

    The old version of the module has been renamed to bsddb185 and is no longer built automatically; you’ll have to edit Modules/Setup to enable it. Note that the new bsddb package is intended to be compatible with the old module, so be sure to file bugs if you discover any incompatibilities. When upgrading to Python 2.3, if the new interpreter is compiled with a new version of the underlying BerkeleyDB library, you will almost certainly have to convert your database files to the new version. You can do this fairly easily with the new scripts db2pickle.py and pickle2db.py which you will find in the distribution’s Tools/scripts directory. If you’ve already been using the PyBSDDB package and importing it as bsddb3, you will have to change your import statements to import it as bsddb.

  • Новий модуль bz2 є інтерфейсом до бібліотеки стиснення даних bz2. bz2-стиснуті дані зазвичай менші за відповідні zlib-стиснуті дані. (Надав Густаво Німейєр.)

  • У новий модуль datetime додано набір стандартних типів дати/часу. Перегляньте наступний розділ для отримання додаткової інформації.

  • The Distutils Extension class now supports an extra constructor argument named depends for listing additional source files that an extension depends on. This lets Distutils recompile the module if any of the dependency files are modified. For example, if sampmodule.c includes the header file sample.h, you would create the Extension object like this:

    ext = Extension("samp",
                    sources=["sampmodule.c"],
                    depends=["sample.h"])
    

    Зміна sample.h призведе до перекомпіляції модуля. (Надав Джеремі Гілтон.)

  • Other minor changes to Distutils: it now checks for the CC, CFLAGS, CPP, LDFLAGS, and CPPFLAGS environment variables, using them to override the settings in Python’s configuration (contributed by Robert Weber).

  • Previously the doctest module would only search the docstrings of public methods and functions for test cases, but it now also examines private ones as well. The DocTestSuite() function creates a unittest.TestSuite object from a set of doctest tests.

  • Нова функція gc.get_referents(object) повертає список усіх об’єктів, на які посилається object.

  • The getopt module gained a new function, gnu_getopt(), that supports the same arguments as the existing getopt() function but uses GNU-style scanning mode. The existing getopt() stops processing options as soon as a non-option argument is encountered, but in GNU-style mode processing continues, meaning that options and arguments can be mixed. For example:

    >>> 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'])
    

    (Надав Пітер Естранд.)

  • Модулі grp, pwd і resource тепер повертають розширені кортежі:

    >>> import grp
    >>> g = grp.getgrnam('amk')
    >>> g.gr_name, g.gr_gid
    ('amk', 500)
    
  • Модуль gzip тепер може обробляти файли розміром понад 2 ГіБ.

  • The new heapq module contains an implementation of a heap queue algorithm. A heap is an array-like data structure that keeps items in a partially sorted order such that, for every index k, heap[k] <= heap[2*k+1] and heap[k] <= heap[2*k+2]. This makes it quick to remove the smallest item, and inserting a new item while maintaining the heap property is O(log n). (See https://xlinux.nist.gov/dads//HTML/priorityque.html for more information about the priority queue data structure.)

    The heapq module provides heappush() and heappop() functions for adding and removing items while maintaining the heap property on top of some other mutable Python sequence type. Here’s an example that uses a Python list:

    >>> 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]
    

    (Надав Кевін О’Коннор.)

  • The IDLE integrated development environment has been updated using the code from the IDLEfork project (https://idlefork.sourceforge.net). The most notable feature is that the code being developed is now executed in a subprocess, meaning that there’s no longer any need for manual reload() operations. IDLE’s core code has been incorporated into the standard library as the idlelib package.

  • Модуль imaplib тепер підтримує IMAP через SSL. (Пірс Лаудер і Тіно Ланге.)

  • The itertools contains a number of useful functions for use with iterators, inspired by various functions provided by the ML and Haskell languages. For example, itertools.ifilter(predicate, iterator) returns all elements in the iterator for which the function predicate() returns True, and itertools.repeat(obj, N) returns obj N times. There are a number of other functions in the module; see the package’s reference documentation for details. (Contributed by Raymond Hettinger.)

  • Дві нові функції в модулі math, degrees(rads) і radians(degs), конвертують між радіанами та градусами. Інші функції в модулі math, такі як math.sin() і math.cos(), завжди вимагали вхідних значень, виміряних у радіанах. Також до math.log() було додано необов’язковий аргумент base, щоб полегшити обчислення логарифмів для основ, відмінних від e і 10. (Надав Реймонд Геттінгер.)

  • Several new POSIX functions (getpgid(), killpg(), lchown(), loadavg(), major(), makedev(), minor(), and mknod()) were added to the posix module that underlies the os module. (Contributed by Gustavo Niemeyer, Geert Jansen, and Denis S. Otkidach.)

  • In the os module, the *stat() family of functions can now report fractions of a second in a timestamp. Such time stamps are represented as floats, similar to the value returned by time.time().

    During testing, it was found that some applications will break if time stamps are floats. For compatibility, when using the tuple interface of the stat_result time stamps will be represented as integers. When using named fields (a feature first introduced in Python 2.2), time stamps are still represented as integers, unless os.stat_float_times() is invoked to enable float return values:

    >>> os.stat("/tmp").st_mtime
    1034791200
    >>> os.stat_float_times(True)
    >>> os.stat("/tmp").st_mtime
    1034791200.6335014
    

    У Python 2.4 значення за замовчуванням зміниться на завжди повертати числа з плаваючою точкою.

    Application developers should enable this feature only if all their libraries work properly when confronted with floating-point time stamps, or if they use the tuple API. If used, the feature should be activated on an application level instead of trying to enable it on a per-use basis.

  • Модуль optparse містить новий синтаксичний аналізатор аргументів командного рядка, який може конвертувати значення параметрів у певний тип Python і автоматично генеруватиме повідомлення про використання. Перегляньте наступний розділ для отримання додаткової інформації.

  • The old and never-documented linuxaudiodev module has been deprecated, and a new version named ossaudiodev has been added. The module was renamed because the OSS sound drivers can be used on platforms other than Linux, and the interface has also been tidied and brought up to date in various ways. (Contributed by Greg Ward and Nicholas FitzRoy-Dale.)

  • Новий модуль platform містить ряд функцій, які намагаються визначити різні властивості платформи, на якій ви працюєте. Є функції для отримання архітектури, типу ЦП, версії ОС Windows і навіть версії дистрибутива Linux. (Надав Марк-Андре Лембург.)

  • The parser objects provided by the pyexpat module can now optionally buffer character data, resulting in fewer calls to your character data handler and therefore faster performance. Setting the parser object’s buffer_text attribute to True will enable buffering.

  • The sample(population, k) function was added to the random module. population is a sequence or xrange object containing the elements of a population, and sample() chooses k elements from the population without replacing chosen elements. k can be any value up to len(population). For example:

    >>> days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'St', 'Sn']
    >>> random.sample(days, 3)      # Choose 3 elements
    ['St', 'Sn', 'Th']
    >>> random.sample(days, 7)      # Choose 7 elements
    ['Tu', 'Th', 'Mo', 'We', 'St', 'Fr', 'Sn']
    >>> random.sample(days, 7)      # Choose 7 again
    ['We', 'Mo', 'Sn', 'Fr', 'Tu', 'St', 'Th']
    >>> random.sample(days, 8)      # Can't choose eight
    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)   # Choose ten odd nos. under 10000
    [3407, 3805, 1505, 7023, 2401, 2267, 9733, 3151, 8083, 9195]
    

    Модуль random тепер використовує новий алгоритм, Mersenne Twister, реалізований у C. Він швидший і детальніше вивчений, ніж попередній алгоритм.

    (Усі зміни внесено Реймондом Геттінгером.)

  • The readline module also gained a number of new functions: get_history_item(), get_current_history_length(), and redisplay().

  • The rexec and Bastion modules have been declared dead, and attempts to import them will fail with a RuntimeError. New-style classes provide new ways to break out of the restricted execution environment provided by rexec, and no one has interest in fixing them or time to do so. If you have applications using rexec, rewrite them to use something else.

    (Sticking with Python 2.2 or 2.1 will not make your applications any safer because there are known bugs in the rexec module in those versions. To repeat: if you’re using rexec, stop using it immediately.)

  • The rotor module has been deprecated because the algorithm it uses for encryption is not believed to be secure. If you need encryption, use one of the several AES Python modules that are available separately.

  • Модуль shutil отримав функцію move(src, dest), яка рекурсивно переміщує файл або каталог до нового розташування.

  • Підтримку вдосконаленої обробки сигналів POSIX було додано до signal, але потім знову вилучено, оскільки виявилося неможливим забезпечити його надійну роботу на різних платформах.

  • Модуль socket тепер підтримує тайм-аути. Ви можете викликати метод settimeout(t) для об’єкта сокета, щоб встановити час очікування t секунд. Подальші операції з сокетом, які тривають більше t секунд, перериваються та викликають виняток socket.timeout.

    Оригінальна реалізація тайм-ауту була створена Тімом О’Меллі. Майкл Гілфікс інтегрував його в модуль Python socket і перевірив його через довгий огляд. Після перевірки коду Гвідо ван Россум переписав його частини. (Це хороший приклад процесу спільної розробки в дії.)

  • У Windows модуль socket тепер поставляється з підтримкою Secure Sockets Layer (SSL).

  • The value of the C PYTHON_API_VERSION macro is now exposed at the Python level as sys.api_version. The current exception can be cleared by calling the new sys.exc_clear() function.

  • Новий модуль tarfile дозволяє читати та записувати в архівні файли у форматі tar. (Надав Ларс Густебель.)

  • The new textwrap module contains functions for wrapping strings containing paragraphs of text. The wrap(text, width) function takes a string and returns a list containing the text split into lines of no more than the chosen width. The fill(text, width) function returns a single string, reformatted to fit into lines no longer than the chosen width. (As you can guess, fill() is built on top of wrap(). For example:

    >>> 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.
    >>>
    

    The module also contains a TextWrapper class that actually implements the text wrapping strategy. Both the TextWrapper class and the wrap() and fill() functions support a number of additional keyword arguments for fine-tuning the formatting; consult the module’s documentation for details. (Contributed by Greg Ward.)

  • The thread and threading modules now have companion modules, dummy_thread and dummy_threading, that provide a do-nothing implementation of the thread module’s interface for platforms where threads are not supported. The intention is to simplify thread-aware modules (ones that don’t rely on threads to run) by putting the following code at the top:

    try:
        import threading as _threading
    except ImportError:
        import dummy_threading as _threading
    

    In this example, _threading is used as the module name to make it clear that the module being used is not necessarily the actual threading module. Code can call functions and use classes in _threading whether or not threads are supported, avoiding an if statement and making the code slightly clearer. This module will not magically make multithreaded code run without threads; code that waits for another thread to return or to do something will simply hang forever.

  • The time module’s strptime() function has long been an annoyance because it uses the platform C library’s strptime() implementation, and different platforms sometimes have odd bugs. Brett Cannon contributed a portable implementation that’s written in pure Python and should behave identically on all platforms.

  • The new timeit module helps measure how long snippets of Python code take to execute. The timeit.py file can be run directly from the command line, or the module’s Timer class can be imported and used directly. Here’s a short example that figures out whether it’s faster to convert an 8-bit string to Unicode by appending an empty Unicode string to it or by using the unicode() function:

    import timeit
    
    timer1 = timeit.Timer('unicode("abc")')
    timer2 = timeit.Timer('"abc" + u""')
    
    # Run three trials
    print timer1.repeat(repeat=3, number=100000)
    print timer2.repeat(repeat=3, number=100000)
    
    # On my laptop this outputs:
    # [0.36831796169281006, 0.37441694736480713, 0.35304892063140869]
    # [0.17574405670166016, 0.18193507194519043, 0.17565798759460449]
    
  • The Tix module has received various bug fixes and updates for the current version of the Tix package.

  • The Tkinter module now works with a thread-enabled version of Tcl. Tcl’s threading model requires that widgets only be accessed from the thread in which they’re created; accesses from another thread can cause Tcl to panic. For certain Tcl interfaces, Tkinter will now automatically avoid this when a widget is accessed from a different thread by marshalling a command, passing it to the correct thread, and waiting for the results. Other interfaces can’t be handled automatically but Tkinter will now raise an exception on such an access so that you can at least find out about the problem. See https://mail.python.org/pipermail/python-dev/2002-December/031107.html for a more detailed explanation of this change. (Implemented by Martin von Löwis.)

  • Calling Tcl methods through _tkinter no longer returns only strings. Instead, if Tcl returns other objects those objects are converted to their Python equivalent, if one exists, or wrapped with a _tkinter.Tcl_Obj object if no Python equivalent exists. This behavior can be controlled through the wantobjects() method of tkapp objects.

    When using _tkinter through the Tkinter module (as most Tkinter applications will), this feature is always activated. It should not cause compatibility problems, since Tkinter would always convert string results to Python types where possible.

    If any incompatibilities are found, the old behavior can be restored by setting the wantobjects variable in the Tkinter module to false before creating the first tkapp object.

    import Tkinter
    Tkinter.wantobjects = 0
    

    Будь-яку поломку, спричинену цією зміною, слід повідомити як помилку.

  • The UserDict module has a new DictMixin class which defines all dictionary methods for classes that already have a minimum mapping interface. This greatly simplifies writing classes that need to be substitutable for dictionaries, such as the classes in the shelve module.

    Adding the mix-in as a superclass provides the full dictionary interface whenever the class defines __getitem__(), __setitem__(), __delitem__(), and keys(). For example:

    >>> import UserDict
    >>> class SeqDict(UserDict.DictMixin):
    ...     """Dictionary lookalike implemented with lists."""
    ...     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)      # See that other dictionary methods are implemented
    ['__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']
    

    (Надав Реймонд Геттінгер.)

  • The DOM implementation in xml.dom.minidom can now generate XML output in a particular encoding by providing an optional encoding argument to the toxml() and toprettyxml() methods of DOM nodes.

  • The xmlrpclib module now supports an XML-RPC extension for handling nil data values such as Python’s None. Nil values are always supported on unmarshalling an XML-RPC response. To generate requests containing None, you must supply a true value for the allow_none parameter when creating a Marshaller instance.

  • The new DocXMLRPCServer module allows writing self-documenting XML-RPC servers. Run it in demo mode (as a program) to see it in action. Pointing the web browser to the RPC server produces pydoc-style documentation; pointing xmlrpclib to the server allows invoking the actual methods. (Contributed by Brian Quinlan.)

  • Додано підтримку інтернаціоналізованих доменних імен (RFC 3454, 3490, 3491 і 3492). Кодування «idna» можна використовувати для перетворення між доменним іменем Unicode і ASCII-сумісним кодуванням (ACE) цього імені.

    >{}>{}> u"www.Alliancefrançaise.nu".encode("idna")
    'www.xn--alliancefranaise-npb.nu'
    

    The socket module has also been extended to transparently convert Unicode hostnames to the ACE version before passing them to the C library. Modules that deal with hostnames such as httplib and ftplib) also support Unicode host names; httplib also sends HTTP Host headers using the ACE version of the domain name. urllib supports Unicode URLs with non-ASCII host names as long as the path part of the URL is ASCII only.

    Для впровадження цієї зміни було додано модуль stringprep, інструмент mkstringprep і кодування punycode.

Тип дати/часу

Типи дати та часу, придатні для вираження позначок часу, були додані як модуль datetime. Типи не підтримують різні календарі чи багато модних функцій і лише дотримуються основ представлення часу.

The three primary types are: date, representing a day, month, and year; time, consisting of hour, minute, and second; and datetime, which contains all the attributes of both date and time. There’s also a timedelta class representing differences between two points in time, and time zone logic is implemented by classes inheriting from the abstract tzinfo class.

You can create instances of date and time by either supplying keyword arguments to the appropriate constructor, e.g. datetime.date(year=1972, month=10, day=15), or by using one of a number of class methods. For example, the today() class method returns the current local date.

Після створення екземпляри класів дати/часу залишаються незмінними. Існує кілька методів створення форматованих рядків з об’єктів:

>>> import datetime
>>> now = datetime.datetime.now()
>>> now.isoformat()
'2002-12-30T21:27:03.994956'
>>> now.ctime()  # Only available on date, datetime
'Mon Dec 30 21:27:03 2002'
>>> now.strftime('%Y %d %b')
'2002 30 Dec'

The replace() method allows modifying one or more fields of a date or datetime instance, returning a new instance:

>>> 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)
>>>

Instances can be compared, hashed, and converted to strings (the result is the same as that of isoformat()). date and datetime instances can be subtracted from each other, and added to timedelta instances. The largest missing feature is that there’s no standard library support for parsing strings and getting back a date or datetime.

Для отримання додаткової інформації зверніться до довідкової документації модуля. (Надав Тім Пітерс.)

Модуль optparse

Модуль getopt забезпечує простий аналіз аргументів командного рядка. Новий модуль optparse (початкова назва Optik) забезпечує більш детальний аналіз командного рядка, який відповідає умовам Unix, автоматично створює вихід для --help і може виконувати різні дії для різних параметрів .

You start by creating an instance of OptionParser and telling it what your program’s options are.

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')

Parsing a command line is then done by calling the parse_args() method.

options, args = op.parse_args(sys.argv[1:])
print options
print args

Це повертає об’єкт, що містить усі значення параметрів, і список рядків, що містять решту аргументів.

Виклик сценарію з різними аргументами тепер працює так, як ви очікували. Зауважте, що аргумент довжини автоматично перетворюється на ціле число.

$ ./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 був написаний Грегом Уордом із пропозиціями читачів Getopt SIG.

Pymalloc: спеціалізований розподільник об’єктів

Pymalloc, спеціалізований розподільник об’єктів, написаний Володимиром Марангозовим, був функцією, доданою до Python 2.1. Pymalloc має бути швидшим за системний malloc() і мати менше витрат пам’яті для шаблонів розподілу, типових для програм Python. Розподільник використовує функцію C malloc(), щоб отримати великі пули пам’яті, а потім виконує менші запити пам’яті з цих пулів.

У версіях 2.1 і 2.2 pymalloc був експериментальною функцією і не був увімкнений за замовчуванням; ви повинні були явно ввімкнути його під час компіляції Python, надавши опцію --with-pymalloc сценарію configure. У версії 2.3 pymalloc отримав додаткові вдосконалення, і тепер він увімкнено за замовчуванням; вам доведеться вказати --without-pymalloc, щоб вимкнути його.

Ця зміна прозора для коду, написаного на Python; однак pymalloc може виявити помилки в розширеннях C. Автори модулів розширення C повинні протестувати свій код із увімкненим pymalloc, оскільки деякий неправильний код може спричинити дамп ядра під час виконання.

Є одна особливо поширена помилка, яка викликає проблеми. В API C 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().

  • To allocate and free Python objects, use the «object» family PyObject_New, PyObject_NewVar, and PyObject_Del().

Завдяки великій роботі Тіма Пітерса, pymalloc у версії 2.3 також надає функції налагодження для виявлення перезапису пам’яті та подвійного звільнення в обох модулях розширення та в самому інтерпретаторі. Щоб увімкнути цю підтримку, скомпілюйте версію інтерпретатора Python для налагодження, запустивши configure з --with-pydebug.

Щоб допомогти розробникам розширень, файл заголовка Misc/pymemcompat.h поширюється разом із джерелом для Python 2.3, який дозволяє розширенням Python використовувати інтерфейси 2.3 для розподілу пам’яті під час компіляції з будь-якою версією Python, починаючи з 1.5.2. Ви повинні скопіювати файл із вихідного коду Python і об’єднати його з джерелом вашого розширення.

Дивись також

https://hg.python.org/cpython/file/default/Objects/obmalloc.c

Щоб отримати повну інформацію про реалізацію pymalloc, перегляньте коментарі у верхній частині файлу Objects/obmalloc.c у вихідному коді Python. Наведене вище посилання вказує на файл у браузері python.org SVN.

Зміни збірки та C API

Зміни в процесі збирання Python і в API C включають:

  • Реалізація виявлення циклу, яка використовується для збирання сміття, виявилася стабільною, тому тепер вона стала обов’язковою. Ви більше не можете скомпілювати Python без нього, а перемикач --with-cycle-gc на configure видалено.

  • Python тепер можна опціонально створити як спільну бібліотеку (libpython2.3.so), вказавши --enable-shared під час виконання сценарію configure Python. (Надав Ондрей Палковський.)

  • The DL_EXPORT and DL_IMPORT macros are now deprecated. Initialization functions for Python extension modules should now be declared using the new macro PyMODINIT_FUNC, while the Python core will generally use the PyAPI_FUNC and PyAPI_DATA macros.

  • Інтерпретатор може бути скомпільований без будь-яких рядків документації для вбудованих функцій і модулів, надаючи --without-doc-strings до сценарію configure. Це робить виконуваний файл Python приблизно на 10% меншим, але також означатиме, що ви не зможете отримати допомогу для вбудованих компонентів Python. (Надав Густаво Німейєр.)

  • The PyArg_NoArgs() macro is now deprecated, and code that uses it should be changed. For Python 2.2 and later, the method definition table can specify the METH_NOARGS flag, signalling that there are no arguments, and the argument checking can then be removed. If compatibility with pre-2.2 versions of Python is important, the code could use PyArg_ParseTuple(args, "") instead, but this will be slower than using METH_NOARGS.

  • PyArg_ParseTuple() accepts new format characters for various sizes of unsigned integers: B for unsigned char, H for unsigned short int, I for unsigned int, and K for unsigned long long.

  • Нову функцію PyObject_DelItemString(mapping, char *key) було додано як скорочення для PyObject_DelItem(mapping, PyString_New(key)).

  • Файлові об’єкти тепер керують своїм внутрішнім рядковим буфером по-іншому, збільшуючи його експоненціально за потреби. Це призводить до значного прискорення тестів у Lib/test/test_bufio.py (з 57 секунд до 1,7 секунд, згідно з одним вимірюванням).

  • It’s now possible to define class and static methods for a C extension type by setting either the METH_CLASS or METH_STATIC flags in a method’s PyMethodDef structure.

  • Python тепер містить копію вихідного коду синтаксичного аналізатора Expat XML, усуваючи будь-яку залежність від версії системи або локальної інсталяції Expat.

  • If you dynamically allocate type objects in your extension, you should be aware of a change in the rules relating to the __module__ and __name__ attributes. In summary, you will want to ensure the type’s dictionary contains a '__module__' key; making the module name the part of the type name leading up to the final period will no longer have the desired effect. For more detail, read the API reference documentation or the source.

Зміни, що стосуються порту

Support for a port to IBM’s OS/2 using the EMX runtime environment was merged into the main Python source tree. EMX is a POSIX emulation layer over the OS/2 system APIs. The Python port for EMX tries to support all the POSIX-like capability exposed by the EMX runtime, and mostly succeeds; fork() and fcntl() are restricted by the limitations of the underlying emulation layer. The standard OS/2 port, which uses IBM’s Visual Age compiler, also gained support for case-sensitive import semantics as part of the integration of the EMX port into CVS. (Contributed by Andrew MacIntyre.)

У MacOS більшість модулів панелі інструментів були слабко зв’язані, щоб покращити зворотну сумісність. Це означає, що модулі більше не будуть завантажуватися, якщо в поточній версії ОС відсутня одна процедура. Натомість виклик відсутньої підпрограми призведе до виключення. (Надав Джек Янсен.)

Файли специфікацій RPM, знайдені в каталозі Misc/RPM/ вихідного коду Python, було оновлено до версії 2.3. (Надав Шон Райфшнайдер.)

Інші нові платформи, які зараз підтримуються Python, включають AtheOS (http://www.atheos.cx/), GNU/Hurd і OpenVMS.

Інші зміни та виправлення

Як завжди, була купа інших покращень і виправлень помилок, розкиданих по дереву вихідних кодів. Пошук у журналах змін 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 extensions that access the f_lineno field of frame objects should instead call PyCode_Addr2Line(f->f_code, f->f_lasti). This will have the added effect of making the code work as desired under «python -O» in earlier versions of Python.

    A nifty new feature is that trace functions can now assign to the f_lineno attribute of frame objects, changing the line that will be executed next. A jump command has been added to the pdb debugger taking advantage of this new feature. (Implemented by Richie Hindle.)

Перенесення на Python 2.3

У цьому розділі перераховано описані раніше зміни, які можуть потребувати змін у вашому коді:

  • yield тепер завжди є ключовим словом; якщо воно використовується як ім’я змінної у вашому коді, потрібно вибрати інше ім’я.

  • Для рядків X і Y «X в Y» тепер працює, якщо X містить більше одного символу.

  • Конструктор типу int() тепер повертатиме довге ціле число замість того, щоб викликати OverflowError, коли рядок або число з плаваючою комою занадто велике, щоб поміститися в ціле число.

  • Якщо у вас є рядки Unicode, які містять 8-бітові символи, ви повинні оголосити кодування файлу (UTF-8, Latin-1 або інше), додавши коментар у верхній частині файлу. Перегляньте розділ PEP 263: Кодування вихідного коду для отримання додаткової інформації.

  • Calling Tcl methods through _tkinter no longer returns only strings. Instead, if Tcl returns other objects those objects are converted to their Python equivalent, if one exists, or wrapped with a _tkinter.Tcl_Obj object if no Python equivalent exists.

  • Великі вісімкові та шістнадцяткові літерали, такі як 0xffffffff, тепер викликають FutureWarning. Наразі вони зберігаються як 32-розрядні числа та отримують від’ємне значення, але в Python 2.4 вони стануть додатними довгими цілими числами.

    Є кілька способів виправити це попередження. Якщо вам справді потрібне позитивне число, просто додайте L до кінця літералу. Якщо ви намагаєтеся отримати 32-розрядне ціле число з установленими молодшими бітами і раніше використовували такий вираз, як ~(1 << 31), ймовірно, найзрозуміліше почати з усіма встановленими бітами та очистити потрібний верхній біти. Наприклад, щоб очистити лише верхній біт (біт 31), ви можете написати 0xffffffffL &~(1L<<31).

  • Ви більше не можете вимкнути твердження, призначивши __debug__.

  • The Distutils setup() function has gained various new keyword arguments such as depends. Old versions of the Distutils will abort if passed unknown keywords. A solution is to check for the presence of the new get_distutil_options() function in your setup.py and only uses the new keywords with a version of the Distutils that supports them:

    from distutils import core
    
    kw = {'sources': 'foo.c', ...}
    if hasattr(core, 'get_distutil_options'):
        kw['depends'] = ['foo.h']
    ext = Extension(**kw)
    
  • Використання None як назви змінної тепер призведе до попередження SyntaxWarning.

  • Назви типів розширень, визначені модулями, що входять до Python, тепер містять модуль і '.' перед назвою типу.

Подяки

Автор хотів би подякувати наступним людям за пропозиції, виправлення та допомогу з різними чернетками цієї статті: Джефф Бауер, Саймон Бруннінг, Бретт Кеннон, Майкл Чермсайд, Ендрю Далк, Скотт Девід Деніелс, Фред Л. Дрейк молодший, Девід Фрейзер, Келлі Гербер, Реймонд Геттінгер, Майкл Хадсон, Кріс Ламберт, Детлеф Ланнерт, Мартін фон Левіс, Ендрю Макінтайр, Лало Мартінс, Чад Нетцер, Густаво Німейєр, Ніл Норвіц, Ханс Новак, Кріс Ріді, Франческо Ріккарді, Віней Саджип, Ніл Шеменауер, Роман Сузі, Джейсон Тішлер, Юст ван Россум.