Що нового в Python 2.1

Автор:

A.M. Kuchling

вступ

У цій статті пояснюються нові функції Python 2.1. Хоча у версії 2.1 не так багато змін, як у Python 2.0, все ж є деякі приємні сюрпризи. 2.1 є першим випуском, який керується використанням Python Enhancement Proposals або PEP, тому більшість значних змін супроводжуються PEP, які надають більш повну документацію та обґрунтування зміни. Ця стаття не намагається повністю задокументувати нові функції, а просто надає огляд нових функцій для програмістів Python. Зверніться до документації Python 2.1 або до конкретного PEP, щоб дізнатися більше про будь-яку нову функцію, яка вас особливо цікавить.

Одна з нещодавніх цілей команди розробників Python полягала в тому, щоб пришвидшити темп випуску нових випусків, причому новий випуск виходить кожні 6-9 місяців. 2.1 є першим випуском, який вийшов таким швидким темпом, з першою альфа-версією, яка з’явилася в січні, через 3 місяці після виходу остаточної версії 2.0.

Остаточний випуск Python 2.1 був зроблений 17 квітня 2001 року.

PEP 227: Вкладені області

Найбільша зміна в Python 2.1 стосується правил визначення області видимості Python. У Python 2.0 у будь-який момент часу існує щонайбільше три простори імен, які використовуються для пошуку імен змінних: локальний, на рівні модуля та вбудований простір імен. Це часто дивувало людей, оскільки не відповідало їхнім інтуїтивним очікуванням. Наприклад, визначення вкладеної рекурсивної функції не працює:

def f():
    ...
    def g(value):
        ...
        return g(value-1) + 1
    ...

The function g() will always raise a NameError exception, because the binding of the name g isn’t in either its local namespace or in the module-level namespace. This isn’t much of a problem in practice (how often do you recursively define interior functions like this?), but this also made using the lambda expression clumsier, and this was a problem in practice. In code which uses lambda you can often find local variables being copied by passing them as the default values of arguments.

def find(self, name):
    "Return list of any entries equal to 'name'"
    L = filter(lambda x, name=name: x == name,
               self.list_attribute)
    return L

У результаті цього значно погіршується читабельність коду Python, написаного у сильно функціональному стилі.

Найсуттєвіша зміна Python 2.1 полягає в тому, що для вирішення цієї проблеми до мови додано статичне визначення області видимості. Як перший ефект, аргумент за замовчуванням name=name тепер непотрібний у наведеному вище прикладі. Простіше кажучи, коли заданому імені змінної не присвоєно значення у функції (за допомогою призначення або операторів def, class або import), посилання на змінна буде шукатися в локальному просторі імен охоплюючої області. Більш детальне пояснення правил і опис реалізації можна знайти в PEP.

Ця зміна може спричинити деякі проблеми сумісності для коду, де те саме ім’я змінної використовується як на рівні модуля, так і як локальна змінна у функції, яка містить додаткові визначення функцій. Це здається малоймовірним, оскільки такий код було б досить заплутаним для читання.

Одним із побічних ефектів змін є те, що оператори from module import * і exec були зроблені незаконними в межах функції за певних умов. У довідковому посібнику Python весь час говорилося, що from module import * допустимо лише на верхньому рівні модуля, але інтерпретатор CPython ніколи раніше не виконував цього. Як частина реалізації вкладених областей, компілятор, який перетворює джерело Python на байт-коди, має згенерувати інший код для доступу до змінних у місткій області. from module import * і exec не дозволяють компілятору це зрозуміти, оскільки вони додають імена до локального простору імен, які невідомі під час компіляції. Таким чином, якщо функція містить визначення функції або lambda вирази з вільними змінними, компілятор позначить це, викликавши виняток SyntaxError.

Щоб зробити попереднє пояснення трохи зрозумілішим, ось приклад:

x = 1
def f():
    # The next line is a syntax error
    exec 'x=2'
    def g():
        return x

Line 4 containing the exec statement is a syntax error, since exec would define a new local variable named x whose value should be accessed by g().

Це не повинно бути великим обмеженням, оскільки exec рідко використовується в більшості коду Python (і коли він використовується, це часто свідчить про поганий дизайн).

Занепокоєння щодо сумісності призвело до поступового впровадження вкладених областей; у Python 2.1 вони не ввімкнені за замовчуванням, але їх можна ввімкнути в модулі за допомогою оператора future, як описано в PEP 236. (Див. наступний розділ для подальшого обговорення PEP 236.) У Python 2.2 вкладені області стануть типовими, і не буде можливості їх вимкнути, але користувачі матимуть весь час життя 2.1, щоб усунути будь-яку поломку внаслідок їх введення.

Дивись також

PEP 227 - Статично вкладені області

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

PEP 236: директиви __future__

Реакцією на вкладені області було широко поширене занепокоєння щодо небезпеки злому коду з випуском 2.1, і воно було досить сильним, щоб змусити Pythoneers застосувати більш консервативний підхід. Цей підхід полягає у введенні угоди про ввімкнення додаткової функціональності у випуску N, який стане обов’язковим у випуску N+1.

Синтаксис використовує оператор from...import із використанням зарезервованої назви модуля __future__. Вкладені області можна активувати наступним оператором:

from __future__ import nested_scopes

Хоча це виглядає як звичайний оператор import, це не так; існують суворі правила щодо того, де можна розмістити таку майбутню заяву. Вони можуть бути лише у верхній частині модуля та повинні передувати будь-якому коду Python або звичайним операторам import. Це тому, що такі оператори можуть впливати на те, як компілятор байт-коду Python аналізує код і генерує байт-код, тому вони повинні передувати будь-якому оператору, який призведе до створення байт-кодів.

Дивись також

PEP 236 - Назад у __future__

Написаний Тімом Пітерсом, а в основному реалізований Джеремі Гілтоном.

PEP 207: багаті порівняння

In earlier versions, Python’s support for implementing comparisons on user-defined classes and extension types was quite simple. Classes could implement a __cmp__() method that was given two instances of a class, and could only return 0 if they were equal or +1 or -1 if they weren’t; the method couldn’t raise an exception or return anything other than a Boolean value. Users of Numeric Python often found this model too weak and restrictive, because in the number-crunching programs that numeric Python is used for, it would be more useful to be able to perform elementwise comparisons of two matrices, returning a matrix containing the results of a given comparison for each element. If the two matrices are of different sizes, then the compare has to be able to raise an exception to signal the error.

У Python 2.1 для підтримки цієї потреби було додано розширені порівняння. Класи Python тепер можуть окремо перевантажувати кожну з операцій <, <=, >, >=, == і !=. Назви нових магічних методів:

Операція

Назва методу

<

__lt__()

<=

__le__()

>

__gt__()

>=

__ge__()

==

__eq__()

!=

__ne__()

(Чарівні методи названо на честь відповідних операторів Fortran .LT.. .LE. тощо. Цифрові програмісти майже напевно добре знайомі з цими назвами та легко їх запам’ятають.)

Кожен із цих чарівних методів має форму method(self, other), де self буде об’єктом ліворуч від оператора, а other буде об’єктом з правого боку. Наприклад, вираз A < B призведе до виклику A.__lt__(B).

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

The built-in cmp(A,B) function can use the rich comparison machinery, and now accepts an optional argument specifying which comparison operation to use; this is given as one of the strings "<", "<=", ">", ">=", "==", or "!=". If called without the optional third argument, cmp() will only return -1, 0, or +1 as in previous versions of Python; otherwise it will call the appropriate method and can return any Python object.

Є також відповідні зміни, які цікавлять програмістів на C; є новий слот tp_richcmp в об’єктах типу та API для виконання певного розширеного порівняння. Я не буду тут розповідати про C API, але відсилаю вас до PEP 207 або до документації C API 2.1, щоб отримати повний список пов’язаних функцій.

Дивись також

PEP 207 - багаті порівняння

Написаний Гвідо ван Россумом, значною мірою заснований на попередніх роботах Девіда Ашера та реалізований Гвідо ван Россумом.

PEP 230: Попередження

За 10 років існування Python накопичив певну кількість застарілих модулів і функцій. Важко визначити, коли функцію безпечно видалити, оскільки неможливо дізнатися, скільки коду її використовує — можливо, жодна програма не залежить від функції, або, можливо, багато хто залежить від цієї функції. Щоб уможливити видалення старих функцій у більш структурований спосіб, було додано рамку попереджень. Коли розробники Python хочуть позбутися функції, це спочатку викличе попередження в наступній версії Python. Наступна версія Python може відмовитися від цієї функції, і користувачі матимуть повний цикл випуску, щоб усунути використання старої функції.

Python 2.1 додає структуру попереджень для використання в цій схемі. Він додає модуль warnings, який надає функції для видачі попереджень і для фільтрації попереджень, які ви не бажаєте відображати. Сторонні модулі також можуть використовувати цю структуру, щоб відмовитися від старих функцій, які вони більше не хочуть підтримувати.

For example, in Python 2.1 the regex module is deprecated, so importing it causes a warning to be printed:

>>> import regex
__main__:1: DeprecationWarning: the regex module
         is deprecated; please use the re module
>>>

Попередження можна видати, викликавши функцію warnings.warn():

warnings.warn("feature X no longer supported")

Перший параметр – це попереджувальне повідомлення; додаткові необов’язкові параметри можуть використовуватися для визначення певної категорії попередження.

Filters can be added to disable certain warnings; a regular expression pattern can be applied to the message or to the module name in order to suppress a warning. For example, you may have a program that uses the regex module and not want to spare the time to convert it to use the re module right now. The warning can be suppressed by calling

import warnings
warnings.filterwarnings(action = 'ignore',
                        message='.*regex module is deprecated',
                        category=DeprecationWarning,
                        module = '__main__')

This adds a filter that will apply only to warnings of the class DeprecationWarning triggered in the __main__ module, and applies a regular expression to only match the message about the regex module being deprecated, and will cause such warnings to be ignored. Warnings can also be printed only once, printed every time the offending code is executed, or turned into exceptions that will cause the program to stop (unless the exceptions are caught in the usual way, of course).

До API C Python також додано функції для видачі попереджень; подробиці зверніться до PEP 230 або до документації Python API.

Дивись також

PEP 5 - Рекомендації щодо розвитку мови

Написав Пол Прескод, щоб визначити процедури, яких слід дотримуватися під час видалення старих функцій з Python. Політика, описана в цьому PEP, не була офіційно прийнята, але остаточна політика, ймовірно, не надто відрізнятиметься від пропозиції Prescod.

PEP 230 - Рамка попереджень

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

PEP 229: Нова система побудови

Під час компіляції Python користувач мав зайти та відредагувати файл Modules/Setup, щоб увімкнути різні додаткові модулі; стандартний набір відносно малий і обмежений модулями, які компілюються на більшості платформ Unix. Це означає, що на платформах Unix із набагато більшою кількістю можливостей, особливо Linux, встановлення Python часто не містять усіх корисних модулів, які могли б.

Python 2.0 додав Distutils, набір модулів для розповсюдження та встановлення розширень. У Python 2.1 Distutils використовуються для компіляції більшої частини стандартної бібліотеки модулів розширення, автоматично визначаючи, які з них підтримуються на поточній машині. Є надія, що це зробить інсталяцію Python простішою та функціональнішою.

Замість того, щоб редагувати файл Modules/Setup, щоб увімкнути модулі, сценарій setup.py у верхньому каталозі дистрибутива вихідного коду Python запускається під час збирання та намагається виявити які модулі можна ввімкнути, перевіривши модулі та файли заголовків у системі. Якщо модуль налаштовано в Modules/Setup, сценарій setup.py не намагатиметься скомпілювати цей модуль і звернеться до вмісту файлу Modules/Setup. Це надає спосіб визначити будь-які дивні прапори командного рядка або бібліотеки, які потрібні для певної платформи.

В іншій далекосяжній зміні механізму збірки Ніл Шеменауер змінив структуру так, що Python тепер використовує єдиний make-файл, який не є рекурсивним, замість make-файлів у верхньому каталозі та в кожному Підкаталоги з Python/, Parser/, Objects/ і Modules/. Це робить створення Python швидшим, а також робить злам Makefiles зрозумілішим і простішим.

Дивись також

PEP 229 - Використання Distutils для створення Python

Написана та реалізована А.М. Кухлінг.

PEP 205: Слабкі посилання

Слабкі посилання, доступні через модуль weakref, є другорядним, але корисним новим типом даних у наборі інструментів програміста Python.

Зберігання посилання на об’єкт (скажімо, у словнику чи списку) має побічним ефектом збереження цього об’єкта назавжди. Є кілька конкретних випадків, коли така поведінка є небажаною, найпоширенішим є кешування об’єктів, а іншим є циклічні посилання в структурах даних, таких як дерева.

Наприклад, розглянемо функцію запам’ятовування, яка кешує результати іншої функції f(x), зберігаючи аргумент функції та її результат у словнику:

_cache = {}
def memoize(x):
    if _cache.has_key(x):
        return _cache[x]

    retval = f(x)

    # Cache the returned object
    _cache[x] = retval

    return retval

This version works for simple things such as integers, but it has a side effect; the _cache dictionary holds a reference to the return values, so they’ll never be deallocated until the Python process exits and cleans up. This isn’t very noticeable for integers, but if f() returns an object, or a data structure that takes up a lot of memory, this can be a problem.

Слабкі посилання забезпечують спосіб реалізації кешу, який не зберігатиме об’єкти живими понад час. Якщо об’єкт доступний лише через слабкі посилання, об’єкт буде звільнено, а слабкі посилання тепер вказуватимуть, що об’єкт, на який він посилався, більше не існує. Слабке посилання на об’єкт obj створюється шляхом виклику wr = weakref.ref(obj). Об’єкт, на який посилається, повертається шляхом виклику слабкого посилання, як якщо б це була функція: wr(). Він поверне об’єкт, на який посилається, або «Немає», якщо об’єкт більше не існує.

This makes it possible to write a memoize() function whose cache doesn’t keep objects alive, by storing weak references in the cache.

_cache = {}
def memoize(x):
    if _cache.has_key(x):
        obj = _cache[x]()
        # If weak reference object still exists,
        # return it
        if obj is not None: return obj

    retval = f(x)

    # Cache a weak reference
    _cache[x] = weakref.ref(retval)

    return retval

The weakref module also allows creating proxy objects which behave like weak references — an object referenced only by proxy objects is deallocated – but instead of requiring an explicit call to retrieve the object, the proxy transparently forwards all operations to the object as long as the object still exists. If the object is deallocated, attempting to use a proxy will cause a weakref.ReferenceError exception to be raised.

proxy = weakref.proxy(obj)
proxy.attr   # Equivalent to obj.attr
proxy.meth() # Equivalent to obj.meth()
del obj
proxy.attr   # raises weakref.ReferenceError

Дивись також

PEP 205 - Слабкі посилання

Написаний і реалізований Фредом Л. Дрейком-молодшим.

PEP 232: Атрибути функцій

In Python 2.1, functions can now have arbitrary information attached to them. People were often using docstrings to hold information about functions and methods, because the __doc__ attribute was the only way of attaching any information to a function. For example, in the Zope web application server, functions are marked as safe for public access by having a docstring, and in John Aycock’s SPARK parsing framework, docstrings hold parts of the BNF grammar to be parsed. This overloading is unfortunate, since docstrings are really intended to hold a function’s documentation; for example, it means you can’t properly document functions intended for private use in Zope.

Довільні атрибути тепер можна встановлювати та отримувати для функцій за допомогою звичайного синтаксису Python:

def f(): pass

f.publish = 1
f.secure = 1
f.grammar = "A ::= B (C D)*"

The dictionary containing attributes can be accessed as the function’s __dict__. Unlike the __dict__ attribute of class instances, in functions you can actually assign a new dictionary to __dict__, though the new value is restricted to a regular Python dictionary; you can’t be tricky and set it to a UserDict instance, or any other random object that behaves like a mapping.

Дивись також

PEP 232 - Атрибути функції

Написав і реалізував Баррі Варшау.

PEP 235: Імпорт модулів на платформах без урахування регістру

Деякі операційні системи мають файлові системи, які не чутливі до регістру, MacOS і Windows є основними прикладами; у цих системах неможливо розрізнити назви файлів FILE.PY і file.py, навіть якщо вони зберігають назву файлу в оригінальному регістрі (вони також зберігають регістр).

У Python 2.1 оператор import працюватиме для імітації чутливості до регістру на платформах, які не чутливі до регістру. Тепер Python буде шукати перший збіг з урахуванням регістру за замовчуванням, викликаючи ImportError, якщо такий файл не знайдено, тому import file не імпортуватиме модуль з назвою FILE.PY. Зіставлення без урахування регістру можна запитати, встановивши змінну середовища PYTHONCASEOK перед запуском інтерпретатора Python.

PEP 217: інтерактивний дисплей

Під час використання інтерпретатора Python в інтерактивному режимі вихід команд відображається за допомогою вбудованої функції repr(). У Python 2.1 змінна sys.displayhook() може бути встановлена на викликаний об’єкт, який буде викликатися замість repr(). Наприклад, ви можете встановити для нього спеціальну функцію красивого друку:

>>> # Create a recursive data structure
... L = [1,2,3]
>>> L.append(L)
>>> L # Show Python's default output
[1, 2, 3, [...]]
>>> # Use pprint.pprint() as the display function
... import sys, pprint
>>> sys.displayhook = pprint.pprint
>>> L
[1, 2, 3,  <Recursion on list with id=135143996>]
>>>

Дивись також

PEP 217 - Дисплей Хук для інтерактивного використання

Написав і реалізував Моше Задка.

PEP 208: Нова модель примусу

Спосіб виконання числового приведення на рівні C було значно змінено. Це вплине лише на авторів розширень C для Python, надаючи їм більше гнучкості в написанні типів розширень, які підтримують числові операції.

Типи розширень тепер можуть установлювати прапор типу Py_TPFLAGS_CHECKTYPES у своїй структурі PyTypeObject, щоб вказати, що вони підтримують нову модель примусу. У таких типах розширень функції числового слота більше не можуть припускати, що їм будуть передані два аргументи одного типу; натомість їм можуть бути передані два аргументи різних типів, і потім вони можуть виконувати власний внутрішній примус. Якщо функції слота передано тип, який вона не може обробити, вона може вказувати на помилку, повертаючи посилання на одноэлементне значення Py_NotImplemented. Потім буде випробувано числові функції іншого типу, і, можливо, вони зможуть впоратися з операцією; якщо інший тип також повертає Py_NotImplemented, тоді буде викликано TypeError. Числові методи, написані на Python, також можуть повертати Py_NotImplemented, змушуючи інтерпретатор діяти так, ніби метод не існує (можливо, викликаючи TypeError, можливо, намагаючись використовувати числові методи іншого об’єкта).

Дивись також

PEP 208 - Переробка моделі примусу

Написаний і реалізований Нілом Шеменауером, значною мірою заснований на попередніх роботах Марка-Андре Лембурга. Прочитайте це, щоб зрозуміти тонкощі того, як числові операції тепер оброблятимуться на рівні C.

PEP 241: Метадані в пакетах Python

A common complaint from Python users is that there’s no single catalog of all the Python modules in existence. T. Middleton’s Vaults of Parnassus at www.vex.net/parnassus/ (retired in February 2009, available in the Internet Archive Wayback Machine) was the largest catalog of Python modules, but registering software at the Vaults is optional, and many people did not bother.

Як перший невеликий крок до вирішення проблеми, програмне забезпечення Python, упаковане за допомогою команди Distutils sdist, міститиме файл під назвою PKG-INFO, що містить інформацію про пакунок, як-от його назву, версію та автора. (метадані, в термінології каталогізації). PEP 241 містить повний список полів, які можуть міститися у файлі PKG-INFO. Оскільки люди почали пакувати своє програмне забезпечення за допомогою Python 2.1, все більше і більше пакетів включатимуть метадані, що дає змогу створювати автоматизовані системи каталогізації та експериментувати з ними. З отриманим досвідом, можливо, стане можливим створити справді хороший каталог, а потім створити його підтримку в Python 2.2. Наприклад, команди Distutils sdist і bdist_* можуть підтримувати опцію upload, яка автоматично завантажуватиме ваш пакет на сервер каталогу.

Ви можете почати створювати пакунки, що містять PKG-INFO, навіть якщо ви не використовуєте Python 2.1, оскільки для користувачів попередніх версій Python буде створено новий випуск Distutils. Версія 1.0.2 Distutils містить зміни, описані в PEP 241, а також різні виправлення помилок і вдосконалення. Він буде доступний у Distutils SIG за адресою https://www.python.org/community/sigs/current/distutils-sig/.

Дивись також

PEP 241 - метадані для програмних пакетів Python

Написана та реалізована А.М. Кухлінг.

PEP 243 - Механізм завантаження сховища модулів

Цей проект PEP, написаний Шоном Райфшнайдером, описує запропонований механізм для завантаження пакетів Python на центральний сервер.

Нові та вдосконалені модулі

  • Ka-Ping Yee contributed two new modules: inspect.py, a module for getting information about live Python code, and pydoc.py, a module for interactively converting docstrings to HTML or text. As a bonus, Tools/scripts/pydoc, which is now automatically installed, uses pydoc.py to display documentation given a Python module, package, or class name. For example, pydoc xml.dom displays the following:

    Python Library Documentation: package xml.dom in xml
    
    NAME
        xml.dom - W3C Document Object Model implementation for Python.
    
    FILE
        /usr/local/lib/python2.1/xml/dom/__init__.pyc
    
    DESCRIPTION
        The Python mapping of the Document Object Model is documented in the
        Python Library Reference in the section on the xml.dom package.
    
        This package contains the following modules:
          ...
    

    pydoc також містить інтерактивний довідковий браузер на основі Tk. pydoc швидко викликає звикання; Спробуй!

  • Two different modules for unit testing were added to the standard library. The doctest module, contributed by Tim Peters, provides a testing framework based on running embedded examples in docstrings and comparing the results against the expected output. PyUnit, contributed by Steve Purcell, is a unit testing framework inspired by JUnit, which was in turn an adaptation of Kent Beck’s Smalltalk testing framework. See https://pyunit.sourceforge.net/ for more information about PyUnit.

  • The difflib module contains a class, SequenceMatcher, which compares two sequences and computes the changes required to transform one sequence into the other. For example, this module can be used to write a tool similar to the Unix diff program, and in fact the sample program Tools/scripts/ndiff.py demonstrates how to write such a script.

  • curses.panel, оболонку для бібліотеки панелей, частину ncurses і проклять SYSV, надав Томас Геллекум. Бібліотека панелей надає вікна з додатковою функцією глибини. Вікна можна переміщувати вище або нижче в порядку глибини, а бібліотека панелей визначає, де панелі перекриваються та які розділи видно.

  • The PyXML package has gone through a few releases since Python 2.0, and Python 2.1 includes an updated version of the xml package. Some of the noteworthy changes include support for Expat 1.2 and later versions, the ability for Expat parsers to handle files in any encoding supported by Python, and various bugfixes for SAX, DOM, and the minidom module.

  • Ping також вніс ще один хук для обробки неперехоплених винятків. sys.excepthook() можна встановити на об’єкт, що викликається. Якщо виняток не перехоплюється жодним блоком tryexcept, виняток буде передано до sys.excepthook(), який потім може робити все, що забажає. На Дев’ятій конференції Python Ping продемонстрував застосування для цього хука: друк розширеного трасування, яке не лише містить перелік фреймів стека, але також перераховує аргументи функції та локальні змінні для кожного фрейму.

  • Various functions in the time module, such as asctime() and localtime(), require a floating point argument containing the time in seconds since the epoch. The most common use of these functions is to work with the current time, so the floating point argument has been made optional; when a value isn’t provided, the current time will be used. For example, log file entries usually need a string containing the current time; in Python 2.1, time.asctime() can be used, instead of the lengthier time.asctime(time.localtime(time.time())) that was previously required.

    Цю зміну запропонував і впровадив Томас Воутерс.

  • Модуль ftplib тепер за замовчуванням отримує файли в пасивному режимі, оскільки пасивний режим, швидше за все, працюватиме за брандмауером. Цей запит надійшов від системи відстеження помилок Debian, оскільки інші пакунки Debian використовують ftplib для отримання файлів, а потім не працюють через брандмауер. Вважається малоймовірним, що це спричинить комусь проблеми, оскільки Netscape за замовчуванням використовує пасивний режим, і мало хто скаржиться, але якщо пасивний режим не підходить для вашої програми чи налаштувань мережі, викличте set_pasv(0) для об’єктів FTP, щоб вимкнути пасивний режим.

  • До модуля socket, наданого Грантом Едвардсом, додано підтримку необробленого доступу до сокетів.

  • Модуль pstats тепер містить простий інтерактивний браузер статистики для відображення профілів часу для програм Python, викликаних, коли модуль запускається як сценарій. Надав Ерік С. Реймонд.

  • Додано нову залежну від реалізації функцію sys._getframe([depth]) для повернення заданого об’єкта кадру з поточного стеку викликів. sys._getframe() повертає кадр у верхній частині стека викликів; якщо вказано додатковий цілочисельний аргумент depth, функція повертає кадр, який depth викликає нижче верхньої частини стека. Наприклад, sys._getframe(1) повертає об’єкт кадру викликаючого.

    Ця функція присутня лише в CPython, а не в Jython або реалізації .NET. Використовуйте його для налагодження та втримайтеся від спокуси вставити його у робочий код.

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

У Python 2.1 було внесено відносно небагато менших змін через коротший цикл випуску. Пошук у журналах змін CVS виявив 117 застосованих виправлень і 136 виправлених помилок; обидві цифри, ймовірно, занижені. Деякі з найбільш помітних змін:

  • A specialized object allocator is now optionally available, that should be faster than the system malloc() and have less memory overhead. The allocator uses C’s malloc() function to get large pools of memory, and then fulfills smaller memory requests from these pools. It can be enabled by providing the --with-pymalloc option to the configure script; see Objects/obmalloc.c for the implementation details.

    Authors of C extension modules should test their code with the object allocator enabled, because some incorrect code may break, causing core dumps at runtime. There are a bunch of memory allocation functions in Python’s C API that have previously been just aliases for the C library’s malloc() and free(), meaning that if you accidentally called mismatched functions, the error wouldn’t be noticeable. When the object allocator is enabled, these functions aren’t aliases of malloc() and free() any more, and calling the wrong function to free memory will get you a core dump. For example, if memory was allocated using PyMem_New, it has to be freed using PyMem_Del(), not free(). A few modules included with Python fell afoul of this and had to be fixed; doubtless there are more third-party modules that will have the same problem.

    Розподільник об’єктів надав Володимир Марангозов.

  • The speed of line-oriented file I/O has been improved because people often complain about its lack of speed, and because it’s often been used as a naïve benchmark. The readline() method of file objects has therefore been rewritten to be much faster. The exact amount of the speedup will vary from platform to platform depending on how slow the C library’s getc() was, but is around 66%, and potentially much faster on some particular operating systems. Tim Peters did much of the benchmarking and coding for this change, motivated by a discussion in comp.lang.python.

    A new module and method for file objects was also added, contributed by Jeff Epler. The new method, xreadlines(), is similar to the existing xrange() built-in. xreadlines() returns an opaque sequence object that only supports being iterated over, reading a line on every iteration but not reading the entire file into memory as the existing readlines() method does. You’d use it like this:

    for line in sys.stdin.xreadlines():
        # ... do something for each line ...
        ...
    

    Для детальнішого обговорення змін лінії вводу-виводу дивіться резюме python-dev за 1–15 січня 2001 року на https://mail.python.org/pipermail/python-dev/2001-January/.

  • A new method, popitem(), was added to dictionaries to enable destructively iterating through the contents of a dictionary; this can be faster for large dictionaries because there’s no need to construct a list containing all the keys or values. D.popitem() removes a random (key, value) pair from the dictionary D and returns it as a 2-tuple. This was implemented mostly by Tim Peters and Guido van Rossum, after a suggestion and preliminary patch by Moshe Zadka.

  • Модулі тепер можуть контролювати, які імена імпортуються, коли використовується from module import *, визначаючи атрибут __all__, що містить список імен, які будуть імпортовані. Однією з поширених скарг є те, що якщо модуль імпортує інші модулі, такі як sys або string, from module import * додасть їх до простору імен модуля імпорту. Щоб виправити це, просто перелічіть загальнодоступні імена в __all__:

    # List public names
    __all__ = ['Database', 'open']
    

    Більш сувору версію цього патча вперше запропонував і реалізував Бен Вольфсон, але після деякого обговорення розробників python була перевірена слабша остаточна версія.

  • Застосування repr() до рядків, які раніше використовували вісімкові символи для недрукованих символів; наприклад, новий рядок був ''\012'. Це був рудиментарний слід походження Python C, але сьогодні вісімкова система має дуже мало практичного використання. Ka-Ping Yee запропонував використовувати шістнадцяткові символи замість вісімкових, а також використовувати символи \n, \t, \r для відповідних символів, і реалізував це нове форматування.

  • Синтаксичні помилки, виявлені під час компіляції, тепер можуть викликати винятки, що містять назву файлу та номер рядка помилки, приємний побічний ефект реорганізації компілятора, виконаної Джеремі Гілтоном.

  • C extensions which import other modules have been changed to use PyImport_ImportModule(), which means that they will use any import hooks that have been installed. This is also encouraged for third-party extensions that need to import some other module from C code.

  • Завдяки Фредріку Лунду розмір бази даних символів Unicode було зменшено ще на 340 КБ.

  • Додано кілька нових портів: MacOS X (від Стівена Маєвського), Cygwin (від Джейсона Тішлера); RISCOS (автор Дітмар Швертбергер); Unixware 7 (автор Billy G. Allie).

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

Подяки

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