Що нового в Python 2.5¶
- Автор:
A.M. Kuchling
У цій статті пояснюються нові функції Python 2.5. Остаточний випуск Python 2.5 заплановано на серпень 2006 року; PEP 356 описує запланований графік випуску. Python 2.5 був випущений 19 вересня 2006 року.
The changes in Python 2.5 are an interesting mix of language and library
improvements. The library enhancements will be more important to Python’s user
community, I think, because several widely useful packages were added. New
modules include ElementTree for XML processing (xml.etree.ElementTree),
the SQLite database module (sqlite3), and the ctypes
module for calling C functions.
Мовні зміни мають середнє значення. Було додано кілька приємних нових функцій, але більшість із них не є функціями, якими ви будете користуватися щодня. Умовні вирази нарешті були додані до мови за допомогою нового синтаксису; див. розділ PEP 308: Умовні вирази. Новий оператор „with“ полегшить написання коду очищення (розділ PEP 343: оператор «з».). Тепер значення можна передавати в генератори (розділ PEP 342: Нові функції генератора). Імпорт тепер відображається як абсолютний або відносний (розділ PEP 328: Абсолютний і відносний імпорт). Деякі кутові випадки обробки винятків обробляються краще (розділ PEP 341: Уніфікована спроба/окрім/нарешті). Усі ці вдосконалення варті уваги, але це вдосконалення тієї чи іншої функції мови; жодна з них не є широкою модифікацією семантики Python.
Окрім мовних і бібліотечних доповнень, у всьому дереві вихідних кодів було зроблено інші покращення та виправлення помилок. Пошук у журналах змін SVN виявив, що між Python 2.4 і 2.5 було застосовано 353 виправлення та 458 виправлених помилок. (Обидві цифри, ймовірно, занижені.)
Ця стаття не намагається бути повною специфікацією нових функцій; натомість зміни коротко представлені з використанням корисних прикладів. Щоб отримати повну інформацію, завжди звертайтеся до документації для Python 2.5 на https://docs.python.org. Якщо ви хочете зрозуміти повну реалізацію та обґрунтування дизайну, зверніться до PEP для конкретної нової функції.
Коментарі, пропозиції та звіти про помилки щодо цього документа вітаються; будь ласка, надішліть їх електронною поштою автору або відкрийте помилку в системі відстеження помилок Python.
PEP 308: Умовні вирази¶
Протягом тривалого часу люди запитували спосіб написання умовних виразів, які є виразами, які повертають значення A або значення B залежно від того, чи є логічне значення true або false. Умовний вираз дає змогу написати один оператор присвоєння, який має той самий ефект, що й наступний:
if condition:
x = true_value
else:
x = false_value
Були нескінченні нудні дискусії щодо синтаксису як на python-dev, так і на comp.lang.python. Навіть було проведено голосування, яке виявило, що більшість виборців бажали використовувати умовні вирази в тій чи іншій формі, але не було жодного синтаксису, якому віддала б перевагу явна більшість. Серед кандидатів C cond ? true_v : false_v, if cond then true_v else false_v та 16 інших варіантів.
Зрештою Гвідо ван Россум обрав дивовижний синтаксис:
x = true_value if condition else false_value
Обчислення, як і в існуючих булевих виразах, все ще є ледачим, тому порядок обчислення трохи змінюється. Вираз умова в середині обчислюється спочатку, а вираз істинне_значення обчислюється, лише якщо умова була істинною. Подібним чином вираз false_value обчислюється лише тоді, коли умова false.
Цей синтаксис може здатися дивним і зворотним; чому умова стоїть у середині виразу, а не в передній частині, як у C c ? x : y? Рішення було перевірено шляхом застосування нового синтаксису до модулів у стандартній бібліотеці та перегляду того, як читається отриманий код. У багатьох випадках, коли використовується умовний вираз, одне значення здається «звичайним випадком», а одне — «винятковим випадком», яке використовується лише в рідкісних випадках, коли умова не виконується. Умовний синтаксис робить цей шаблон трохи очевиднішим:
contents = ((doc + '\n') if doc else '')
Я прочитав наведене вище твердження як значення «тут contents зазвичай присвоюється значення doc+'\n'; іноді doc є порожнім, у цьому особливому випадку повертається порожній рядок». Я сумніваюся, що буду дуже часто використовувати умовні вирази, де немає чіткого загального та незвичайного випадків.
Була деяка дискусія щодо того, чи повинна мова вимагати оточувати умовні вирази дужками. Було прийнято рішення не вимагати дужок у граматиці мови Python, але з точки зору стилю я вважаю, що ви повинні завжди використовувати їх. Розглянемо ці два твердження:
# First version -- no parens
level = 1 if logging else 0
# Second version -- with parens
level = (1 if logging else 0)
Я вважаю, що в першій версії око читача може згрупувати оператор у «level = 1», «if logging», «else 0» і вважати, що умова вирішує, чи виконується призначення level. Друга версія, на мій погляд, читається краще, оскільки в ній чітко видно, що призначення завжди виконується, а вибір здійснюється між двома значеннями.
Ще одна причина включення дужок: кілька дивних комбінацій списків і лямбда-виразів можуть виглядати як неправильні умовні вирази. Перегляньте PEP 308 для деяких прикладів. Якщо ви поставите круглі дужки навколо своїх умовних виразів, ви не зіткнетеся з цим випадком.
Дивись також
- PEP 308 - Умовні вирази
PEP, написаний Гвідо ван Россумом і Раймондом Д. Хеттінгером; реалізований Томасом Воутерсом.
PEP 309: Застосування часткової функції¶
Модуль functools містить інструменти для програмування у функціональному стилі.
One useful tool in this module is the partial() function. For programs
written in a functional style, you’ll sometimes want to construct variants of
existing functions that have some of the parameters filled in. Consider a
Python function f(a, b, c); you could create a new function g(b, c) that
was equivalent to f(1, b, c). This is called «partial function
application».
partial() takes the arguments (function, arg1, arg2, ... kwarg1=value1,
kwarg2=value2). The resulting object is callable, so you can just call it to
invoke function with the filled-in arguments.
Ось маленький, але реалістичний приклад:
import functools
def log (message, subsystem):
"Write the contents of 'message' to the specified subsystem."
print '%s: %s' % (subsystem, message)
...
server_log = functools.partial(log, subsystem='server')
server_log('Unable to open socket')
Here’s another example, from a program that uses PyGTK. Here a context-sensitive
pop-up menu is being constructed dynamically. The callback provided
for the menu option is a partially applied version of the open_item()
method, where the first argument has been provided.
...
class Application:
def open_item(self, path):
...
def init (self):
open_func = functools.partial(self.open_item, item_path)
popup_menu.append( ("Open", open_func, 1) )
Another function in the functools module is the
update_wrapper(wrapper, wrapped) function that helps you write
well-behaved decorators. update_wrapper() copies the name, module, and
docstring attribute to a wrapper function so that tracebacks inside the wrapped
function are easier to understand. For example, you might write:
def my_decorator(f):
def wrapper(*args, **kwds):
print 'Calling decorated function'
return f(*args, **kwds)
functools.update_wrapper(wrapper, f)
return wrapper
wraps() is a decorator that can be used inside your own decorators to copy
the wrapped function’s information. An alternate version of the previous
example would be:
def my_decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwds):
print 'Calling decorated function'
return f(*args, **kwds)
return wrapper
Дивись також
- PEP 309 - Застосування часткової функції
PEP запропонований і написаний Пітером Гаррісом; реалізований Хе-Шік Чангом і Ніком Когланом, з адаптацією Реймонда Геттінгера.
PEP 314: Метадані для програмних пакетів Python v1.1¶
Some simple dependency support was added to Distutils. The setup()
function now has requires, provides, and obsoletes keyword
parameters. When you build a source distribution using the sdist command,
the dependency information will be recorded in the PKG-INFO file.
Іншим новим параметром ключового слова є download_url, який має бути встановлено на URL-адресу вихідного коду пакета. Це означає, що тепер можна шукати запис в індексі пакетів, визначати залежності для пакета та завантажувати необхідні пакети.
VERSION = '1.0'
setup(name='PyPackage',
version=VERSION,
requires=['numarray', 'zlib (>=1.1.4)'],
obsoletes=['OldPackage']
download_url=('http://www.example.com/pypackage/dist/pkg-%s.tar.gz'
% VERSION),
)
Інше нове вдосконалення індексу пакетів Python на https://pypi.org — це зберігання вихідних і двійкових архівів для пакета. Нова команда upload Distutils завантажить пакет до репозиторію.
Перш ніж можна буде завантажити пакет, ви повинні мати можливість створити дистрибутив за допомогою команди sdist Distutils. Коли це запрацює, ви можете запустити python setup.py upload, щоб додати свій пакет до архіву PyPI. За бажанням ви можете підписати пакет GPG, вказавши параметри --sign і --identity.
Завантаження пакетів було реалізовано Мартіном фон Льовісом і Річардом Джонсом.
Дивись також
- PEP 314 - метадані для програмних пакетів Python v1.1
PEP запропонований і написаний А.М. Кухлінг, Річард Джонс і Фред Дрейк; реалізований Річардом Джонсом і Фредом Дрейком.
PEP 328: Абсолютний і відносний імпорт¶
Простіша частина PEP 328 була реалізована в Python 2.4: тепер можна використовувати дужки для включення імен, імпортованих із модуля за допомогою оператора from ... import ..., що полегшує імпорт багато різних імен.
Більш складна частина була реалізована в Python 2.5: для імпорту модуля можна вказати використання абсолютного або відносного імпорту пакетів. План полягає в тому, щоб у майбутніх версіях Python зробити абсолютний імпорт типовим.
Скажімо, у вас є такий каталог пакетів:
pkg/
pkg/__init__.py
pkg/main.py
pkg/string.py
This defines a package named pkg containing the pkg.main and
pkg.string submodules.
Consider the code in the main.py module. What happens if it executes
the statement import string? In Python 2.4 and earlier, it will first look
in the package’s directory to perform a relative import, finds
pkg/string.py, imports the contents of that file as the
pkg.string module, and that module is bound to the name string in the
pkg.main module’s namespace.
That’s fine if pkg.string was what you wanted. But what if you wanted
Python’s standard string module? There’s no clean way to ignore
pkg.string and look for the standard module; generally you had to look at
the contents of sys.modules, which is slightly unclean. Holger Krekel’s
py.std package provides a tidier way to perform imports from the standard
library, import py; py.std.string.join(), but that package isn’t available
on all Python installations.
Reading code which relies on relative imports is also less clear, because a
reader may be confused about which module, string or pkg.string,
is intended to be used. Python users soon learned not to duplicate the names of
standard library modules in the names of their packages“ submodules, but you
can’t protect against having your submodule’s name being used for a new module
added in a future version of Python.
У Python 2.5 ви можете змінити поведінку import на абсолютний імпорт за допомогою директиви from __future__ import absolute_import. Ця поведінка абсолютного імпорту стане типовою в майбутніх версіях (ймовірно, Python 2.7). Якщо абсолютний імпорт встановлено за замовчуванням, import string завжди знаходитиме версію стандартної бібліотеки. Рекомендується, щоб користувачі якомога частіше використовували абсолютний імпорт, тому краще починати писати from pkg import string у вашому коді.
Відносний імпорт все ще можливий, додавши початкову крапку до імені модуля під час використання форми from ... import:
# Import names from pkg.string
from .string import name1, name2
# Import pkg.string
from . import string
This imports the string module relative to the current package, so in
pkg.main this will import name1 and name2 from pkg.string.
Additional leading periods perform the relative import starting from the parent
of the current package. For example, code in the A.B.C module can do:
from . import D # Imports A.B.D
from .. import E # Imports A.E
from ..F import G # Imports A.F.G
Початкові крапки не можна використовувати з формою import modname оператора імпорту, лише з формою from ... import.
Дивись також
- PEP 328 - Імпорт: багаторядковий і абсолютний/відносний
PEP, написаний Aahz; реалізований Томасом Воутерсом.
- https://pylib.readthedocs.io/
The py library by Holger Krekel, which contains the
py.stdpackage.
PEP 338: Виконання модулів як сценаріїв¶
Перемикач -m, доданий у Python 2.4 для виконання модуля як сценарію, отримав кілька додаткових можливостей. Замість того, щоб бути реалізованим у коді C всередині інтерпретатора Python, комутатор тепер використовує реалізацію в новому модулі, runpy.
The runpy module implements a more sophisticated import mechanism so that
it’s now possible to run modules in a package such as pychecker.checker.
The module also supports alternative import mechanisms such as the
zipimport module. This means you can add a .zip archive’s path to
sys.path and then use the -m switch to execute code from the
archive.
Дивись також
- PEP 338 - Виконання модулів у вигляді скриптів
PEP написав і реалізував Нік Коглан.
PEP 341: Уніфікована спроба/окрім/нарешті¶
До Python 2.5 оператор try був у двох варіантах. Ви можете використовувати блок finally, щоб гарантувати, що код завжди виконується, або один чи більше блоків except, щоб перехоплювати певні винятки. Ви не могли поєднати обидва блоки except і блок finally, оскільки генерація правильного байт-коду для комбінованої версії була складною, і було незрозуміло, якою має бути семантика комбінованого оператора бути.
Гвідо ван Россум провів деякий час, працюючи з Java, яка підтримує еквівалент поєднання блоків except і блоку finally, і це прояснило, що має означати цей оператор. У Python 2.5 тепер можна писати:
try:
block-1 ...
except Exception1:
handler-1 ...
except Exception2:
handler-2 ...
else:
else-block
finally:
final-block
The code in block-1 is executed. If the code raises an exception, the various
except blocks are tested: if the exception is of class
Exception1, handler-1 is executed; otherwise if it’s of class
Exception2, handler-2 is executed, and so forth. If no exception is
raised, the else-block is executed.
Незалежно від того, що сталося раніше, final-block виконується після завершення блоку коду та обробки будь-яких викликаних винятків. Навіть якщо сталася помилка в обробнику винятків або else-block і виникає новий виняток, код у final-block все одно виконується.
Дивись також
- PEP 341 - Уніфікація try-except і try-finally
PEP, написаний Георгом Брандлом; виконання Томаса Лі.
PEP 342: Нові функції генератора¶
Python 2.5 додає простий спосіб передачі значень у генератор. Як було введено в Python 2.3, генератори створюють лише вихід; як тільки код генератора був викликаний для створення ітератора, не було можливості передати будь-яку нову інформацію у функцію, коли її виконання відновилося. Іноді можливість передати певну інформацію буде корисною. Хакерські рішення для цього включають змусити код генератора переглядати глобальну змінну, а потім змінювати значення глобальної змінної або передавати якийсь змінний об’єкт, який потім змінюють абоненти.
Щоб оновити вашу пам’ять про основні генератори, ось простий приклад:
def counter (maximum):
i = 0
while i < maximum:
yield i
i += 1
Коли ви викликаєте counter(10), результатом є ітератор, який повертає значення від 0 до 9. Коли зустрічається оператор yield, ітератор повертає надане значення та призупиняє виконання функції, збереження локальних змінних. Виконання поновлюється після наступного виклику методу next() ітератора, який починається після оператора yield.
У Python 2.3 yield був оператором; він не повернув жодного значення. У версії 2.5 yield тепер є виразом, що повертає значення, яке можна призначити змінній або іншим чином оперувати:
val = (yield i)
Я рекомендую вам завжди брати дужки навколо виразу yield, коли ви щось робите з повернутим значенням, як у прикладі вище. Дужки не завжди потрібні, але простіше завжди додавати їх замість того, щоб запам’ятовувати, коли вони потрібні.
(PEP 342 пояснює точні правила, які полягають у тому, що yield-вираз завжди повинен бути взятий у дужки, за винятком випадків, коли він зустрічається у виразі верхнього рівня в правій частині призначення. Це означає, що ви можете написати val = yield i, але повинні використовувати круглі дужки, коли є операція, як у val = (yield i) + 12.)
Значення надсилаються в генератор шляхом виклику його методу send(value). Потім код генератора відновлюється, і вираз yield повертає вказане значення. Якщо викликається звичайний метод next(), yield повертає None.
Ось попередній приклад, змінений, щоб дозволити змінювати значення внутрішнього лічильника.
def counter (maximum):
i = 0
while i < maximum:
val = (yield i)
# If value provided, change counter
if val is not None:
i = val
else:
i += 1
А ось приклад зміни лічильника:
>>> it = counter(10)
>>> print it.next()
0
>>> print it.next()
1
>>> print it.send(8)
8
>>> print it.next()
9
>>> print it.next()
Traceback (most recent call last):
File "t.py", line 15, in ?
print it.next()
StopIteration
yield will usually return None, so you should always check
for this case. Don’t just use its value in expressions unless you’re sure that
the send() method will be the only method used to resume your generator
function.
In addition to send(), there are two other new methods on generators:
throw(type, value=None, traceback=None)використовується для створення винятку всередині генератора; виняток викликає виразyield, де виконання генератора призупинено.close()raises a newGeneratorExitexception inside the generator to terminate the iteration. On receiving this exception, the generator’s code must either raiseGeneratorExitorStopIteration. Catching theGeneratorExitexception and returning a value is illegal and will trigger aRuntimeError; if the function raises some other exception, that exception is propagated to the caller.close()will also be called by Python’s garbage collector when the generator is garbage-collected.Якщо вам потрібно запустити код очищення, коли виникає
GeneratorExit, я пропоную використовувати набірtry: ... finally:замість перехопленняGeneratorExit.
Кумулятивний ефект цих змін полягає в тому, щоб перетворити генераторів з односторонніх виробників інформації на виробників і споживачів.
Генератори також стають сопрограмами, більш узагальненою формою підпрограм. Підпрограми вводяться в одній точці та виходять з іншої точки (верхня частина функції та оператор return), але до підпрограм можна ввійти, вийти з них і відновити їх у багатьох різних точках ( yield заяви). Нам доведеться з’ясувати шаблони для ефективного використання співпрограм у Python.
The addition of the close() method has one side effect that isn’t obvious.
close() is called when a generator is garbage-collected, so this means the
generator’s code gets one last chance to run before the generator is destroyed.
This last chance means that try...finally statements in generators can now
be guaranteed to work; the finally clause will now always get a
chance to run. The syntactic restriction that you couldn’t mix yield
statements with a try...finally suite has therefore been removed. This
seems like a minor bit of language trivia, but using generators and
try...finally is actually necessary in order to implement the
with statement described by PEP 343. I’ll look at this new statement
in the following section.
Another even more esoteric effect of this change: previously, the
gi_frame attribute of a generator was always a frame object. It’s now
possible for gi_frame to be None once the generator has been
exhausted.
Дивись також
- PEP 342 - Співпрограми через розширені генератори
PEP, написаний Гвідо ван Россумом і Філіпом Дж. Ебі; реалізовано Філіпом Дж. Ебі. Містить приклади більш химерного використання генераторів як співпрограм.
Попередні версії цих функцій були запропоновані в PEP 288 Реймондом Геттінгером і PEP 325 Самуелем Педроні.
- https://en.wikipedia.org/wiki/Coroutine
Запис у Вікіпедії для співпрограм.
- https://web.archive.org/web/20160321211320/http://www.sidhe.org/~dan/blog/archives/000178.html
Пояснення співпрограм з точки зору Perl, написане Деном Сугальським.
PEP 343: оператор «з».¶
Інструкція „with“ уточнює код, який раніше використовував блоки try...finally, щоб забезпечити виконання коду очищення. У цьому розділі я обговорю твердження, як воно буде зазвичай використовуватися. У наступному розділі я розгляну деталі реалізації та покажу, як писати об’єкти для використання з цим оператором.
Оператор „with“ — це нова структура потоку керування, основна структура якої:
with expression [as variable]:
with-block
The expression is evaluated, and it should result in an object that supports the
context management protocol (that is, has __enter__() and __exit__()
methods.
The object’s __enter__() is called before with-block is executed and
therefore can run set-up code. It also may return a value that is bound to the
name variable, if given. (Note carefully that variable is not assigned
the result of expression.)
After execution of the with-block is finished, the object’s __exit__()
method is called, even if the block raised an exception, and can therefore run
clean-up code.
Щоб увімкнути оператор у Python 2.5, вам потрібно додати таку директиву до свого модуля:
from __future__ import with_statement
Оператор завжди буде ввімкнено в Python 2.6.
Деякі стандартні об’єкти Python тепер підтримують протокол керування контекстом і можуть використовуватися з оператором „with“. Одним із прикладів є файлові об’єкти:
with open('/etc/passwd', 'r') as f:
for line in f:
print line
... more processing code ...
Після виконання цього оператора файловий об’єкт у f буде автоматично закрито, навіть якщо цикл for викликав виняток під час проходження блоку.
Примітка
In this case, f is the same object created by open(), because
__enter__() returns self.
Блокування та змінні умови модуля threading також підтримують оператор „with“:
lock = threading.Lock()
with lock:
# Critical section of code
...
Блокування встановлюється перед виконанням блоку та завжди знімається після завершення блоку.
The new localcontext() function in the decimal module makes it easy
to save and restore the current decimal context, which encapsulates the desired
precision and rounding characteristics for computations:
from decimal import Decimal, Context, localcontext
# Displays with default precision of 28 digits
v = Decimal('578')
print v.sqrt()
with localcontext(Context(prec=16)):
# All code in this block uses a precision of 16 digits.
# The original context is restored on exiting the block.
print v.sqrt()
Написання менеджерів контексту¶
Під капотом оператор „with“ досить складний. Більшість людей використовуватимуть „with“ тільки в компанії з існуючими об’єктами, і їм не потрібно знати ці деталі, тому ви можете пропустити решту цього розділу, якщо хочете. Авторам нових об’єктів потрібно буде зрозуміти деталі базової реалізації та продовжувати читати.
Загальне пояснення протоколу керування контекстом таке:
The expression is evaluated and should result in an object called a «context manager». The context manager must have
__enter__()and__exit__()methods.The context manager’s
__enter__()method is called. The value returned is assigned to VAR. If no'as VAR'clause is present, the value is simply discarded.Код у BLOCK виконується.
Якщо BLOCK викликає виняток, викликається
__exit__(type, value, traceback)з деталями винятку, ті самі значення, які повертаєsys.exc_info(). Повернене значення методу контролює, чи буде виняток повторно викликаний: будь-яке значення false повторно викликає виняток, аTrueпризведе до його придушення. Ви рідко захочете придушити виняток, тому що, якщо ви це зробите, автор коду, що містить оператор „with“, ніколи не зрозуміє, що щось пішло не так.If BLOCK didn’t raise an exception, the
__exit__()method is still called, but type, value, and traceback are allNone.
Давайте поміркуємо на прикладі. Я не буду представляти детальний код, а лише накидаю методи, необхідні для бази даних, яка підтримує транзакції.
(Для людей, які не знайомі з термінологією бази даних: набір змін до бази даних групується в транзакцію. Транзакції можуть бути або зафіксованими, тобто всі зміни записуються в базу даних, або відкоченими, тобто всі зміни скасовуються та база даних не змінена. Для отримання додаткової інформації зверніться до будь-якого підручника з баз даних.)
Припустімо, що існує об’єкт, що представляє з’єднання з базою даних. Нашою метою буде дозволити користувачеві писати такий код:
db_connection = DatabaseConnection()
with db_connection as cursor:
cursor.execute('insert into ...')
cursor.execute('delete from ...')
# ... more operations ...
The transaction should be committed if the code in the block runs flawlessly or
rolled back if there’s an exception. Here’s the basic interface for
DatabaseConnection that I’ll assume:
class DatabaseConnection:
# Database interface
def cursor (self):
"Returns a cursor object and starts a new transaction"
def commit (self):
"Commits current transaction"
def rollback (self):
"Rolls back current transaction"
The __enter__() method is pretty easy, having only to start a new
transaction. For this application the resulting cursor object would be a useful
result, so the method will return it. The user can then add as cursor to
their „with“ statement to bind the cursor to a variable name.
class DatabaseConnection:
...
def __enter__ (self):
# Code to start a new transaction
cursor = self.cursor()
return cursor
The __exit__() method is the most complicated because it’s where most of
the work has to be done. The method has to check if an exception occurred. If
there was no exception, the transaction is committed. The transaction is rolled
back if there was an exception.
У наведеному нижче коді виконання просто припиниться в кінці функції, повертаючи значення за замовчуванням None. None є хибним, тому виняток буде знову створено автоматично. Якщо ви бажаєте, ви можете бути більш чіткими та додати оператор return у позначене місце.
class DatabaseConnection:
...
def __exit__ (self, type, value, tb):
if tb is None:
# No exception, so commit
self.commit()
else:
# Exception occurred, so rollback.
self.rollback()
# return False
Модуль contextlib¶
Новий модуль contextlib надає деякі функції та декоратор, корисні для написання об’єктів для використання з оператором „with“.
The decorator is called @~contextlib.contextmanager, and lets you write a single
generator function instead of defining a new class. The generator should yield
exactly one value. The code up to the yield will be executed as the
__enter__() method, and the value yielded will be the method’s return
value that will get bound to the variable in the „with“ statement’s
as clause, if any. The code after the yield will be
executed in the __exit__() method. Any exception raised in the block will
be raised by the yield statement.
Наш приклад бази даних із попереднього розділу можна записати за допомогою цього декоратора як:
from contextlib import contextmanager
@contextmanager
def db_transaction (connection):
cursor = connection.cursor()
try:
yield cursor
except:
connection.rollback()
raise
else:
connection.commit()
db = DatabaseConnection()
with db_transaction(db) as cursor:
...
Модуль contextlib також має функцію nested(mgr1, mgr2, ...), яка об’єднує кілька контекстних менеджерів, тому вам не потрібно писати вкладений „with“ заяви. У цьому прикладі один оператор „with“ запускає транзакцію бази даних і отримує блокування потоку:
lock = threading.Lock()
with nested (db_transaction(db), lock) as (cursor, locked):
...
Нарешті, функція closing(object) повертає object, щоб його можна було прив’язати до змінної, і викликає object.close у кінці блоку.
import urllib, sys
from contextlib import closing
with closing(urllib.urlopen('http://www.yahoo.com')) as f:
for line in f:
sys.stdout.write(line)
Дивись також
- PEP 343 - оператор «з».
PEP, написаний Гвідо ван Россумом і Ніком Когланом; реалізований Майком Блендом, Гвідо ван Россумом і Нілом Норвітцем. PEP показує код, згенерований для оператора „
with“, який може бути корисним для вивчення того, як працює оператор.
Документація для модуля contextlib.
PEP 352: Винятки як класи нового стилю¶
Класи винятків тепер можуть бути класами нового стилю, а не лише класичними класами, а також вбудованим класом Exception і всіма стандартними вбудованими винятками (NameError, ValueError, і т.д.) тепер є класами нового стилю.
Ієрархію успадкування для винятків було дещо змінено. У 2.5 відносини успадкування такі:
BaseException # New in Python 2.5
|- KeyboardInterrupt
|- SystemExit
|- Exception
|- (all other current built-in exceptions)
Це перевпорядкування було зроблено, оскільки люди часто хочуть перехопити всі винятки, які вказують на помилки програми. KeyboardInterrupt і SystemExit не є помилками, однак, і зазвичай представляють явну дію, наприклад натискання користувачем Control-C або виклик коду sys.exit() . Голе except: перехопить усі винятки, тому вам зазвичай потрібно перерахувати KeyboardInterrupt і SystemExit, щоб повторно викликати їх. Звичайний шаблон такий:
try:
...
except (KeyboardInterrupt, SystemExit):
raise
except:
# Log error...
# Continue running program...
У Python 2.5 тепер ви можете написати except Exception, щоб досягти того самого результату, перехоплюючи всі винятки, які зазвичай вказують на помилки, але залишаючи KeyboardInterrupt і SystemExit окремо. Як і в попередніх версіях, голе except: усе ще перехоплює всі винятки.
Мета для Python 3.0 полягає в тому, щоб вимагати, щоб будь-який клас, створений як виняток, походив від BaseException або якогось нащадка BaseException, і в майбутніх випусках серії Python 2.x це обмеження може почати застосовуватися. . Тому я пропоную вам почати робити всі ваші класи винятків похідними від Exception зараз. Було запропоновано, що чисту форму except: слід видалити в Python 3.0, але Гвідо ван Россум не вирішив, робити це чи ні.
Викликання рядків як винятків, як у виразі raise "Сталася помилка", застаріло в Python 2.5 і викличе попередження. Мета полягає в тому, щоб мати можливість видалити функцію виключення рядків у кількох випусках.
Дивись також
- PEP 352 - обов’язковий суперклас для винятків
PEP, написаний Бреттом Кенноном і Гвідо ван Россумом; реалізовано Бреттом Кенноном.
PEP 353: використання ssize_t як типу індексу¶
A wide-ranging change to Python’s C API, using a new Py_ssize_t type
definition instead of int, will permit the interpreter to handle more
data on 64-bit platforms. This change doesn’t affect Python’s capacity on 32-bit
platforms.
Various pieces of the Python interpreter used C’s int type to store
sizes or counts; for example, the number of items in a list or tuple were stored
in an int. The C compilers for most 64-bit platforms still define
int as a 32-bit type, so that meant that lists could only hold up to
2**31 - 1 = 2147483647 items. (There are actually a few different
programming models that 64-bit C compilers can use – see
https://unix.org/version2/whatsnew/lp64_wp.html for a discussion – but the
most commonly available model leaves int as 32 bits.)
Обмеження в 2147483647 елементів насправді не має значення на 32-розрядній платформі, тому що у вас закінчиться пам’ять, перш ніж досягнеться обмеження довжини. Кожен елемент списку потребує місця для вказівника, який становить 4 байти, плюс місце для PyObject, що представляє елемент. 2147483647*4 — це вже більше байтів, ніж може вмістити 32-розрядний адресний простір.
It’s possible to address that much memory on a 64-bit platform, however. The pointers for a list that size would only require 16 GiB of space, so it’s not unreasonable that Python programmers might construct lists that large. Therefore, the Python interpreter had to be changed to use some type other than int, and this will be a 64-bit type on 64-bit platforms. The change will cause incompatibilities on 64-bit machines, so it was deemed worth making the transition now, while the number of 64-bit users is still relatively small. (In 5 or 10 years, we may all be on 64-bit machines, and the transition would be more painful then.)
Ця зміна найбільше впливає на авторів модулів розширення C. Рядки Python і типи контейнерів, такі як списки та кортежі, тепер використовують Py_ssize_t для зберігання свого розміру. Такі функції, як PyList_Size() тепер повертають Py_ssize_t. Тому в коді модулів розширення може знадобитися змінити деякі змінні на Py_ssize_t.
The PyArg_ParseTuple() and Py_BuildValue() functions have a new
conversion code, n, for Py_ssize_t. PyArg_ParseTuple()“s
s# and t# still output int by default, but you can define the
macro PY_SSIZE_T_CLEAN before including Python.h to make
them return Py_ssize_t.
PEP 353 містить розділ про вказівки щодо перетворення, який слід прочитати авторам розширень, щоб дізнатися про підтримку 64-розрядних платформ.
Дивись також
- PEP 353 - Використання ssize_t як типу індексу
PEP написаний і реалізований Мартіном фон Льовісом.
PEP 357: метод „__index__“¶
The NumPy developers had a problem that could only be solved by adding a new
special method, __index__(). When using slice notation, as in
[start:stop:step], the values of the start, stop, and step indexes
must all be either integers or long integers. NumPy defines a variety of
specialized integer types corresponding to unsigned and signed integers of 8,
16, 32, and 64 bits, but there was no way to signal that these types could be
used as slice indexes.
Slicing can’t just use the existing __int__() method because that method
is also used to implement coercion to integers. If slicing used
__int__(), floating-point numbers would also become legal slice indexes
and that’s clearly an undesirable behaviour.
Instead, a new special method called __index__() was added. It takes no
arguments and returns an integer giving the slice index to use. For example:
class C:
def __index__ (self):
return self.value
Повернене значення має бути або цілим числом Python, або довгим цілим числом. Інтерпретатор перевірить, чи повернутий тип правильний, і викличе TypeError, якщо ця вимога не виконується.
A corresponding nb_index slot was added to the C-level
PyNumberMethods structure to let C extensions implement this protocol.
PyNumber_Index(obj) can be used in extension code to call the
__index__() function and retrieve its result.
Дивись також
- PEP 357 - Дозволяє використовувати будь-який об’єкт для нарізки
PEP написаний і реалізований Тревісом Оліфантом.
Інші зміни мови¶
Ось усі зміни, які Python 2.5 вносить у основну мову Python.
The
dicttype has a new hook for letting subclasses provide a default value when a key isn’t contained in the dictionary. When a key isn’t found, the dictionary’s__missing__(key)method will be called. This hook is used to implement the newdefaultdictclass in thecollectionsmodule. The following example defines a dictionary that returns zero for any missing key:class zerodict (dict): def __missing__ (self, key): return 0 d = zerodict({1:1, 2:2}) print d[1], d[2] # Prints 1, 2 print d[3], d[4] # Prints 0, 0
І 8-бітні рядки, і рядки Unicode мають нові методи
partition(sep)іrpartition(sep), які спрощують загальний варіант використання.Метод
find(S)часто використовується для отримання індексу, який потім використовується для розрізання рядка та отримання частин, які знаходяться перед і після роздільника.partition(sep)зводить цей шаблон до одного виклику методу, який повертає 3-кортеж, що містить підрядок перед роздільником, сам роздільник і підрядок після роздільника. Якщо роздільник не знайдено, перший елемент кортежу є цілим рядком, а інші два елементи порожні.rpartition(sep)також повертає 3-кортеж, але починає пошук з кінця рядка;rозначає „зворотний“.Деякі приклади:
>>> ('http://www.python.org').partition('://') ('http', '://', 'www.python.org') >>> ('file:/usr/share/doc/index.html').partition('://') ('file:/usr/share/doc/index.html', '', '') >>> (u'Subject: a quick question').partition(':') (u'Subject', u':', u' a quick question') >>> 'www.python.org'.rpartition('.') ('www.python', '.', 'org') >>> 'www.python.org'.rpartition(':') ('', '', 'www.python.org')
(Реалізовано Фредріком Лундом за пропозицією Раймонда Геттінгера.)
The
startswith()andendswith()methods of string types now accept tuples of strings to check for.def is_image_file (filename): return filename.endswith(('.gif', '.jpg', '.tiff'))
(Реалізовано Георгом Брандлом за пропозицією Тома Лінна.)
The
min()andmax()built-in functions gained akeykeyword parameter analogous to thekeyargument forsort(). This parameter supplies a function that takes a single argument and is called for every value in the list;min()/max()will return the element with the smallest/largest return value from this function. For example, to find the longest string in a list, you can do:L = ['medium', 'longest', 'short'] # Prints 'longest' print max(L, key=len) # Prints 'short', because lexicographically 'short' has the largest value print max(L)
(Надано Стівеном Бетардом і Реймондом Геттінгером.)
Дві нові вбудовані функції,
any()іall(), оцінюють, чи містить ітератор значення true або false.any()повертаєTrue, якщо будь-яке значення, яке повертає ітератор, є істинним; інакше він повернеFalse.all()повертаєTrueтільки якщо всі значення, повернуті ітератором, оцінюються як істинні. (Запропоновано Гвідо ван Россумом і реалізовано Раймондом Геттінгером.)The result of a class’s
__hash__()method can now be either a long integer or a regular integer. If a long integer is returned, the hash of that value is taken. In earlier versions the hash value was required to be a regular integer, but in 2.5 theid()built-in was changed to always return non-negative numbers, and users often seem to useid(self)in__hash__()methods (though this is discouraged).ASCII тепер є стандартним кодуванням для модулів. Тепер це синтаксична помилка, якщо модуль містить рядкові літерали з 8-бітовими символами, але не має оголошення кодування. У Python 2.4 це викликало попередження, а не синтаксичну помилку. Перегляньте PEP 263, щоб дізнатися, як оголосити кодування модуля; наприклад, ви можете додати такий рядок у верхній частині вихідного файлу:
# -*- coding: latin1 -*-Нове попередження,
UnicodeWarning, спрацьовує, коли ви намагаєтеся порівняти рядок Unicode з 8-бітним рядком, який не можна перетворити на Unicode за допомогою стандартного кодування ASCII. Результат порівняння false:>>> chr(128) == unichr(128) # Can't convert chr(128) to Unicode __main__:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal False >>> chr(127) == unichr(127) # chr(127) can be converted True
Раніше це викликало виняток
UnicodeDecodeError, але у версії 2.5 це могло призвести до загадкових проблем під час доступу до словника. Якщо ви шукалиunichr(128)іchr(128)використовувався як ключ, ви отримали б винятокUnicodeDecodeError. Інші зміни у 2.5 призвели до того, що цей виняток було викликано замість придушення кодом уdictobject.c, який реалізує словники.Створення винятку для такого порівняння є абсолютно правильним, але зміна могла порушити код, тому замість цього було введено
UnicodeWarning.(Реалізовано Марком-Андре Лембургом.)
Одна з помилок, яку інколи допускають програмісти на Python, полягає в тому, що вони забувають включити модуль
__init__.pyв каталог пакунків. Налагодження цієї помилки може заплутати, і зазвичай вимагає запуску Python з перемикачем-v, щоб реєструвати всі шукані шляхи. У Python 2.5 нове попередженняImportWarningспрацьовує, коли імпорт мав би отримати каталог як пакет, але не було знайдено__init__.py. За замовчуванням це попередження мовчки ігнорується; надайте параметр-Wdпід час запуску виконуваного файлу Python для відображення попереджувального повідомлення. (Реалізовано Томасом Воутерсом.)Список базових класів у визначенні класу тепер може бути порожнім. Як приклад, це зараз законно:
class C(): pass
(Реалізовано Бреттом Кенноном.)
Зміни інтерактивного інтерпретатора¶
В інтерактивному інтерпретаторі quit і exit вже давно є рядками, тому нові користувачі отримують дещо корисне повідомлення, коли вони намагаються вийти:
>>> quit
'Use Ctrl-D (i.e. EOF) to exit.'
У Python 2.5 quit і exit тепер є об’єктами, які все ще створюють рядкові представлення самих себе, але також можуть викликатися. Новачки, які спробують quit() або exit() тепер вийдуть з інтерпретатора, як вони очікують. (Реалізовано Георгом Брандлом.)
Виконуваний файл Python тепер приймає стандартні довгі параметри --help і --version; у Windows він також приймає /? параметр для відображення довідкового повідомлення. (Реалізовано Георгом Брандлом.)
Оптимізації¶
Декілька оптимізацій було розроблено під час спринту NeedForSpeed, заходу, який проходив у Рейк’явіку, Ісландія, 21–28 травня 2006 року. Спринт був зосереджений на підвищенні швидкості реалізації CPython і фінансувався EWT LLC за місцевої підтримки від CCP Games. Ці оптимізації, додані під час цього спринту, спеціально позначені в наступному списку.
Коли вони були представлені в Python 2.4, вбудовані типи
setіfrozensetбули створені поверх типу словника Python. У 2.5 внутрішню структуру даних було налаштовано для реалізації наборів, і в результаті набори використовуватимуть на третину менше пам’яті та будуть дещо швидшими. (Реалізовано Раймондом Хеттінгером.)Швидкість деяких операцій Unicode, таких як пошук підрядків, поділ рядків і кодування та декодування карти символів, покращено. (Фредрік Лунд і Ендрю Далке під час спринту NeedForSpeed удосконалили пошук підрядків і розділення. Карти символів покращили Вальтер Дьорвальд і Мартін фон Льовіс.)
Функція long(str, base) тепер працює швидше з довгими рядками цифр, оскільки обчислюється менше проміжних результатів. Пік припадає на рядки приблизно з 800–1000 цифр, де функція працює в 6 разів швидше. (Надано Аланом Макінтайром і зроблено під час спринту NeedForSpeed.)
It’s now illegal to mix iterating over a file with
for line in fileand calling the file object’sread()/readline()/readlines()methods. Iteration uses an internal buffer and theread*()methods don’t use that buffer. Instead they would return the data following the buffer, causing the data to appear out of order. Mixing iteration and these methods will now trigger aValueErrorfrom theread*()method. (Implemented by Thomas Wouters.)Модуль
structтепер компілює рядки формату структури у внутрішнє представлення та кешує це представлення, що забезпечує 20% прискорення. (Надано Бобом Іполіто під час спринту NeedForSpeed.)Модуль
reотримав прискорення на 1 або 2% завдяки переключенню на функції виділення Python замість системнихmalloc()іfree(). (Надано Джеком Дідеріхом під час спринту NeedForSpeed.)Оптимізатор peephole генератора коду тепер виконує просту постійну згортання виразів. Якщо ви напишете щось на кшталт
a = 2+3, генератор коду виконає арифметику та створить код, що відповідаєa = 5. (Запропоновано та реалізовано Раймондом Хеттінгером.)Виклики функцій тепер швидші, оскільки об’єкти коду тепер зберігають останній готовий кадр («зомбі-кадр») у внутрішньому полі об’єкта коду, повторно використовуючи його під час наступного виклику об’єкта коду. (Оригінальний патч Майкла Хадсона, модифікований Арміном Ріго та Річардом Джонсом; зроблено під час спринту NeedForSpeed.) Об’єкти фрейму також трохи менші, що може покращити локальність кешу та трохи зменшити використання пам’яті. (Надав Ніл Норвіц.)
Вбудовані винятки Python тепер є класами нового стилю, зміна, яка значно прискорює створення екземплярів. Тому обробка винятків у Python 2.5 приблизно на 30% швидша, ніж у 2.4. (Річард Джонс, Георг Брандл і Шон Райфшнайдер на спринті NeedForSpeed.)
Importing now caches the paths tried, recording whether they exist or not so that the interpreter makes fewer
open()andstat()calls on startup. (Contributed by Martin von Löwis and Georg Brandl.)
Нові, покращені та видалені модулі¶
Стандартна бібліотека отримала багато вдосконалень і виправлень помилок у Python 2.5. Ось неповний список найбільш помітних змін, відсортованих за алфавітом назв модулів. Зверніться до файлу Misc/NEWS у дереві вихідних кодів, щоб отримати більш повний список змін, або перегляньте журнали SVN, щоб отримати всі деталі.
The
audioopmodule now supports the a-LAW encoding, and the code for u-LAW encoding has been improved. (Contributed by Lars Immisch.)The
codecsmodule gained support for incremental codecs. Thecodecs.lookup()function now returns aCodecInfoinstance instead of a tuple.CodecInfoinstances behave like a 4-tuple to preserve backward compatibility but also have the attributesencode,decode,incrementalencoder,incrementaldecoder,streamwriter, andstreamreader. Incremental codecs can receive input and produce output in multiple chunks; the output is the same as if the entire input was fed to the non-incremental codec. See thecodecsmodule documentation for details. (Designed and implemented by Walter Dörwald.)The
collectionsmodule gained a new type,defaultdict, that subclasses the standarddicttype. The new type mostly behaves like a dictionary but constructs a default value when a key isn’t present, automatically adding it to the dictionary for the requested key value.The first argument to
defaultdict’s constructor is a factory function that gets called whenever a key is requested but not found. This factory function receives no arguments, so you can use built-in type constructors such aslist()orint(). For example, you can make an index of words based on their initial letter like this:words = """Nel mezzo del cammin di nostra vita mi ritrovai per una selva oscura che la diritta via era smarrita""".lower().split() index = defaultdict(list) for w in words: init_letter = w[0] index[init_letter].append(w)
Друк
indexпризводить до наступного результату:defaultdict(<type 'list'>, {'c': ['cammin', 'che'], 'e': ['era'], 'd': ['del', 'di', 'diritta'], 'm': ['mezzo', 'mi'], 'l': ['la'], 'o': ['oscura'], 'n': ['nel', 'nostra'], 'p': ['per'], 's': ['selva', 'smarrita'], 'r': ['ritrovai'], 'u': ['una'], 'v': ['vita', 'via']}
(Надав Гвідо ван Россум.)
The
dequedouble-ended queue type supplied by thecollectionsmodule now has aremove(value)method that removes the first occurrence of value in the queue, raisingValueErrorif the value isn’t found. (Contributed by Raymond Hettinger.)Новий модуль: Модуль
contextlibмістить допоміжні функції для використання з новим оператором „with“. Перегляньте розділ Модуль contextlib, щоб дізнатися більше про цей модуль.New module: The
cProfilemodule is a C implementation of the existingprofilemodule that has much lower overhead. The module’s interface is the same asprofile: you runcProfile.run('main()')to profile a function, can save profile data to a file, etc. It’s not yet known if the Hotshot profiler, which is also written in C but doesn’t match theprofilemodule’s interface, will continue to be maintained in future versions of Python. (Contributed by Armin Rigo.)Also, the
pstatsmodule for analyzing the data measured by the profiler now supports directing the output to any file object by supplying a stream argument to theStatsconstructor. (Contributed by Skip Montanaro.)The
csvmodule, which parses files in comma-separated value format, received several enhancements and a number of bugfixes. You can now set the maximum size in bytes of a field by calling thecsv.field_size_limit(new_limit)function; omitting the new_limit argument will return the currently set limit. Thereaderclass now has aline_numattribute that counts the number of physical lines read from the source; records can span multiple physical lines, soline_numis not the same as the number of records read.Синтаксичний аналізатор CSV тепер суворіший щодо багаторядкових полів у лапках. Раніше, якщо рядок закінчувався в полі в лапках без кінцевого символу нового рядка, новий рядок вставлявся у поле, що поверталося. Така поведінка викликала проблеми під час читання файлів, які містили символи повернення каретки в межах полів, тому код було змінено, щоб повертати поле без вставки нового рядка. Як наслідок, якщо нові рядки, вбудовані в поля, є важливими, вхідні дані слід розділити на рядки таким чином, щоб зберегти символи нового рядка.
(Надано Скіпом Монтанаро та Ендрю Макнамарою.)
Клас
datetimeв модуліdatetimeтепер має методstrptime(string, format)для аналізу рядків дат, наданий Джошем Споеррі. Він використовує символи того самого формату, що йtime.strptime()іtime.strftime():import datetime as dt ts = dt.datetime.strptime('10:13:15 2006-03-07', '%H:%M:%S %Y-%m-%d')
The
difflib.SequenceMatcher.get_matching_blocks()method in thedifflibmodule now guarantees to return a minimal list of blocks describing matching subsequences. Previously, the algorithm would occasionally break a block of matching elements into two list entries. (Enhancement by Tim Peters.)Модуль
doctestотримав параметрSKIP, який утримує приклад від виконання взагалі. Це призначено для фрагментів коду, які є прикладами використання, призначеними для читача, а насправді не є тестовими випадками.An encoding parameter was added to the
testfile()function and theDocFileSuiteclass to specify the file’s encoding. This makes it easier to use non-ASCII characters in tests contained within a docstring. (Contributed by Bjorn Tillenius.)Пакет
emailоновлено до версії 4.0. (Надав Баррі Варшау.)The
fileinputmodule was made more flexible. Unicode filenames are now supported, and a mode parameter that defaults to"r"was added to theinput()function to allow opening files in binary or universal newlines mode. Another new parameter, openhook, lets you use a function other thanopen()to open the input files. Once you’re iterating over the set of files, theFileInputobject’s newfileno()returns the file descriptor for the currently opened file. (Contributed by Georg Brandl.)In the
gcmodule, the newget_count()function returns a 3-tuple containing the current collection counts for the three GC generations. This is accounting information for the garbage collector; when these counts reach a specified threshold, a garbage collection sweep will be made. The existinggc.collect()function now takes an optional generation argument of 0, 1, or 2 to specify which generation to collect. (Contributed by Barry Warsaw.)The
nsmallest()andnlargest()functions in theheapqmodule now support akeykeyword parameter similar to the one provided by themin()/max()functions and thesort()methods. For example:>>> import heapq >>> L = ["short", 'medium', 'longest', 'longer still'] >>> heapq.nsmallest(2, L) # Return two lowest elements, lexicographically ['longer still', 'longest'] >>> heapq.nsmallest(2, L, key=len) # Return two shortest elements ['short', 'medium']
(Надав Реймонд Геттінгер.)
Функція
itertools.islice()тепер приймаєNoneдля аргументів start і step. Це робить його більш сумісним з атрибутами об’єктів фрагмента, тож тепер ви можете написати наступне:s = slice(5) # Create slice object itertools.islice(iterable, s.start, s.stop, s.step)
(Надав Реймонд Геттінгер.)
The
format()function in thelocalemodule has been modified and two new functions were added,format_string()andcurrency().Параметр val функції
format()раніше міг бути рядком, якщо з’являлося не більше одного специфікатора %char; тепер параметр має бути точно одним специфікатором %char без навколишнього тексту. Також було додано необов’язковий параметр monetary, який, якщоTrue, використовуватиме правила локалі для форматування валюти під час розміщення розділювача між групами з трьох цифр.To format strings with multiple %char specifiers, use the new
format_string()function that works likeformat()but also supports mixing %char specifiers with arbitrary text.A new
currency()function was also added that formats a number according to the current locale’s settings.(Надав Георг Брандл.)
The
mailboxmodule underwent a massive rewrite to add the capability to modify mailboxes in addition to reading them. A new set of classes that includembox,MH, andMaildirare used to read mailboxes, and have anadd(message)method to add messages,remove(key)to remove messages, andlock()/unlock()to lock/unlock the mailbox. The following example converts a maildir-format mailbox into an mbox-format one:import mailbox # 'factory=None' uses email.Message.Message as the class representing # individual messages. src = mailbox.Maildir('maildir', factory=None) dest = mailbox.mbox('/tmp/mbox') for msg in src: dest.add(msg)
(Надано Грегорі К. Джонсоном. Фінансування надано Google Summer of Code 2005 року.)
New module: the
msilibmodule allows creating Microsoft Installer.msifiles and CAB files. Some support for reading the.msidatabase is also included. (Contributed by Martin von Löwis.)The
nismodule now supports accessing domains other than the system default domain by supplying a domain argument to thenis.match()andnis.maps()functions. (Contributed by Ben Bell.)The
operatormodule’sitemgetter()andattrgetter()functions now support multiple fields. A call such asoperator.attrgetter('a', 'b')will return a function that retrieves theaandbattributes. Combining this new feature with thesort()method’skeyparameter lets you easily sort lists using multiple fields. (Contributed by Raymond Hettinger.)The
optparsemodule was updated to version 1.5.1 of the Optik library. TheOptionParserclass gained anepilogattribute, a string that will be printed after the help message, and adestroy()method to break reference cycles created by the object. (Contributed by Greg Ward.)The
osmodule underwent several changes. Thestat_float_timesvariable now defaults to true, meaning thatos.stat()will now return time values as floats. (This doesn’t necessarily mean thatos.stat()will return times that are precise to fractions of a second; not all systems support such precision.)Constants named
os.SEEK_SET,os.SEEK_CUR, andos.SEEK_ENDhave been added; these are the parameters to theos.lseek()function. Two new constants for locking areos.O_SHLOCKandos.O_EXLOCK.Two new functions,
wait3()andwait4(), were added. They’re similar thewaitpid()function which waits for a child process to exit and returns a tuple of the process ID and its exit status, butwait3()andwait4()return additional information.wait3()doesn’t take a process ID as input, so it waits for any child process to exit and returns a 3-tuple of process-id, exit-status, resource-usage as returned from theresource.getrusage()function.wait4(pid)does take a process ID. (Contributed by Chad J. Schroeder.)On FreeBSD, the
os.stat()function now returns times with nanosecond resolution, and the returned object now hasst_genandst_birthtime. Thest_flagsattribute is also available, if the platform supports it. (Contributed by Antti Louko and Diego Pettenò.)Налагоджувач Python, наданий модулем
pdb, тепер може зберігати списки команд, які потрібно виконати, коли досягнуто точки зупинки та припинено виконання. Після створення точки зупину №1 введітькоманди 1та введіть ряд команд, які потрібно виконати, завершивши списоккінець. Список команд може включати команди, які відновлюють виконання, такі якпродовжитиабодалі. (Надано Грегуаром Думсом.)The
pickleandcPicklemodules no longer accept a return value ofNonefrom the__reduce__()method; the method must return a tuple of arguments instead. The ability to returnNonewas deprecated in Python 2.4, so this completes the removal of the feature.Модуль
pkgutil, який містить різноманітні службові функції для пошуку пакунків, було покращено для підтримки перехоплювачів імпорту PEP 302 і тепер також працює для пакунків, що зберігаються в архівах ZIP-формату. (Надав Філіп Дж. Ебі.)Набір тестів pybench від Марка-Андре Лембурга тепер включено до каталогу
Tools/pybench. Набір pybench є вдосконаленням загальновживаної програмиpystone.py, оскільки pybench забезпечує більш детальне вимірювання швидкості інтерпретатора. Замість того, щоб виконувати багато різних операцій і зводити результат до одного числа, як це робитьpystone.py, він відраховує певні операції, такі як виклики функцій, нарізка кортежів, пошук методів і числові операції.The
pyexpatmodule now uses version 2.0 of the Expat parser. (Contributed by Trent Mick.)The
Queueclass provided by thequeuemodule gained two new methods.join()blocks until all items in the queue have been retrieved and all processing work on the items have been completed. Worker threads call the other new method,task_done(), to signal that processing for an item has been completed. (Contributed by Raymond Hettinger.)The old
regexandregsubmodules, which have been deprecated ever since Python 2.0, have finally been deleted. Other deleted modules:statcache,tzparse,whrandom.Also deleted: the
lib-olddirectory, which includes ancient modules such asdircmpandni, was removed.lib-oldwasn’t on the defaultsys.path, so unless your programs explicitly added the directory tosys.path, this removal shouldn’t affect your code.Модуль
rlcompleterбільше не залежить від імпорту модуляreadlineі тому тепер працює на платформах, відмінних від Unix. (Патч від Роберта Кіндла.)The
SimpleXMLRPCServerandDocXMLRPCServerclasses now have arpc_pathsattribute that constrains XML-RPC operations to a limited set of URL paths; the default is to allow only'/'and'/RPC2'. Settingrpc_pathstoNoneor an empty tuple disables this path checking.The
socketmodule now supportsAF_NETLINKsockets on Linux, thanks to a patch from Philippe Biondi. Netlink sockets are a Linux-specific mechanism for communications between a user-space process and kernel code; an introductory article about them is at https://www.linuxjournal.com/article/7356. In Python code, netlink addresses are represented as a tuple of 2 integers,(pid, group_mask).Два нові методи для об’єктів сокетів,
recv_into(buffer)іrecvfrom_into(buffer), зберігають отримані дані в об’єкті, який підтримує протокол буфера, замість того, щоб повертати дані як рядок. Це означає, що ви можете помістити дані безпосередньо в масив або файл із відображенням пам’яті.Socket objects also gained
getfamily(),gettype(), andgetproto()accessor methods to retrieve the family, type, and protocol values for the socket.New module: the
spwdmodule provides functions for accessing the shadow password database on systems that support shadow passwords.The
structis now faster because it compiles format strings intoStructobjects withpack()andunpack()methods. This is similar to how theremodule lets you create compiled regular expression objects. You can still use the module-levelpack()andunpack()functions; they’ll createStructobjects and cache them. Or you can useStructinstances directly:s = struct.Struct('ih3s') data = s.pack(1972, 187, 'abc') year, number, name = s.unpack(data)
Ви також можете пакувати та розпаковувати дані в буферні об’єкти та з них безпосередньо за допомогою методів
pack_into(buffer, offset, v1, v2, ...)іunpack_from(buffer, offset). Це дає змогу зберігати дані безпосередньо в масиві або файлі, відображеному в пам’яті.(
Structobjects were implemented by Bob Ippolito at the NeedForSpeed sprint. Support for buffer objects was added by Martin Blais, also at the NeedForSpeed sprint.)Розробники Python перейшли від CVS до Subversion під час процесу розробки 2.5. Інформація про точну версію збірки доступна як змінна
sys.subversion, 3-кортеж(ім'я-інтерпретатора, ім'я-гілки, діапазон-версій). Наприклад, на момент написання моя копія 2.5 повідомляла про('CPython', 'trunk', '45313:45315').Ця інформація також доступна для розширень C через функцію
Py_GetBuildInfo(), яка повертає рядок інформації про збірку, як це:"trunk:45355:45356M, Apr 13 2006, 07:42:19". (Надав Баррі Варшау.)Інша нова функція,
sys._current_frames(), повертає поточні фрейми стека для всіх запущених потоків як словник, що зіставляє ідентифікатори потоку з найвищим фреймом стека, який зараз активний у цьому потоці на момент виклику функції. (Надав Тім Пітерс.)The
TarFileclass in thetarfilemodule now has anextractall()method that extracts all members from the archive into the current working directory. It’s also possible to set a different directory as the extraction target, and to unpack only a subset of the archive’s members.Стиснення, яке використовується для tar-файлу, відкритого в режимі потоку, тепер можна автоматично визначити за допомогою режиму
'r|*'. (Надав Ларс Густебель.)Модуль
threadingтепер дозволяє встановлювати розмір стеку, який використовується під час створення нових потоків. Функціяstack_size([*size*])повертає поточний налаштований розмір стека, а надання додаткового параметра size встановлює нове значення. Не всі платформи підтримують зміну розміру стека, але Windows, потоки POSIX і OS/2 підтримують. (Надав Ендрю Макінтайр.)The
unicodedatamodule has been updated to use version 4.1.0 of the Unicode character database. Version 3.2.0 is required by some specifications, so it’s still available asunicodedata.ucd_3_2_0.New module: the
uuidmodule generates universally unique identifiers (UUIDs) according to RFC 4122. The RFC defines several different UUID versions that are generated from a starting string, from system properties, or purely randomly. This module contains aUUIDclass and functions nameduuid1(),uuid3(),uuid4(), anduuid5()to generate different versions of UUID. (Version 2 UUIDs are not specified in RFC 4122 and are not supported by this module.)>>> import uuid >>> # make a UUID based on the host ID and current time >>> uuid.uuid1() UUID('a8098c1a-f86e-11da-bd1a-00112444be1e') >>> # make a UUID using an MD5 hash of a namespace UUID and a name >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org') UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e') >>> # make a random UUID >>> uuid.uuid4() UUID('16fd2706-8baf-433b-82eb-8c7fada847da') >>> # make a UUID using a SHA-1 hash of a namespace UUID and a name >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org') UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
(Надано Ка-Пінг Йі.)
The
weakrefmodule’sWeakKeyDictionaryandWeakValueDictionarytypes gained new methods for iterating over the weak references contained in the dictionary.iterkeyrefs()andkeyrefs()methods were added toWeakKeyDictionary, anditervaluerefs()andvaluerefs()were added toWeakValueDictionary. (Contributed by Fred L. Drake, Jr.)The
webbrowsermodule received a number of enhancements. It’s now usable as a script withpython -m webbrowser, taking a URL as the argument; there are a number of switches to control the behaviour (-nfor a new browser window,-tfor a new tab). New module-level functions,open_new()andopen_new_tab(), were added to support this. The module’sopen()function supports an additional feature, an autoraise parameter that signals whether to raise the open window when possible. A number of additional browsers were added to the supported list such as Firefox, Opera, Konqueror, and elinks. (Contributed by Oleg Broytmann and Georg Brandl.)The
xmlrpclibmodule now supports returningdatetimeobjects for the XML-RPC date type. Supplyuse_datetime=Trueto theloads()function or theUnmarshallerclass to enable this feature. (Contributed by Skip Montanaro.)Модуль
zipfileтепер підтримує версію формату ZIP64, тобто архів .zip тепер може бути більшим за 4 ГіБ і містити окремі файли розміром понад 4 ГіБ. (Надав Рональд Уссорен.)The
zlibmodule’sCompressandDecompressobjects now support acopy()method that makes a copy of the object’s internal state and returns a newCompressorDecompressobject. (Contributed by Chris AtLee.)
Пакет ctypes¶
The ctypes package, written by Thomas Heller, has been added to the
standard library. ctypes lets you call arbitrary functions in shared
libraries or DLLs. Long-time users may remember the dl module, which
provides functions for loading shared libraries and calling functions in them.
The ctypes package is much fancier.
To load a shared library or DLL, you must create an instance of the
CDLL class and provide the name or path of the shared library or DLL.
Once that’s done, you can call arbitrary functions by accessing them as
attributes of the CDLL object.
import ctypes
libc = ctypes.CDLL('libc.so.6')
result = libc.printf("Line of output\n")
Type constructors for the various C types are provided: c_int(),
c_float(), c_double(), c_char_p() (equivalent to char*), and so forth. Unlike Python’s types, the C versions are all mutable; you
can assign to their value attribute to change the wrapped value. Python
integers and strings will be automatically converted to the corresponding C
types, but for other types you must call the correct type constructor. (And I
mean must; getting it wrong will often result in the interpreter crashing
with a segmentation fault.)
You shouldn’t use c_char_p() with a Python string when the C function will
be modifying the memory area, because Python strings are supposed to be
immutable; breaking this rule will cause puzzling bugs. When you need a
modifiable memory area, use create_string_buffer():
s = "this is a string"
buf = ctypes.create_string_buffer(s)
libc.strfry(buf)
C functions are assumed to return integers, but you can set the restype
attribute of the function object to change this:
>>> libc.atof('2.71828')
-1783957616
>>> libc.atof.restype = ctypes.c_double
>>> libc.atof('2.71828')
2.71828
ctypes also provides a wrapper for Python’s C API as the
ctypes.pythonapi object. This object does not release the global
interpreter lock before calling a function, because the lock must be held when
calling into the interpreter’s code. There’s a py_object type
constructor that will create a PyObject* pointer. A simple usage:
import ctypes
d = {}
ctypes.pythonapi.PyObject_SetItem(ctypes.py_object(d),
ctypes.py_object("abc"), ctypes.py_object(1))
# d is now {'abc', 1}.
Don’t forget to use py_object(); if it’s omitted you end up with a
segmentation fault.
ctypes існує вже деякий час, але люди все ще пишуть і розповсюджують модулі розширення, створені вручну, тому що ви не можете покладатися на наявність ctypes. Можливо, розробники почнуть писати оболонки Python поверх бібліотеки, доступ до якої здійснюється через ctypes замість модулів розширення, тепер, коли ctypes включено до ядра Python.
Дивись також
- https://web.archive.org/web/20180410025338/http://starship.python.net/crew/theller/ctypes/
The pre-stdlib ctypes web page, with a tutorial, reference, and FAQ.
Документація для модуля ctypes.
Пакет ElementTree¶
A subset of Fredrik Lundh’s ElementTree library for processing XML has been
added to the standard library as xml.etree. The available modules are
ElementTree, ElementPath, and ElementInclude from
ElementTree 1.2.6. The cElementTree accelerator module is also
included.
Решта цього розділу надасть короткий огляд використання ElementTree. Повна документація для ElementTree доступна за адресою https://web.archive.org/web/20201124024954/http://effbot.org/zone/element-index.htm.
ElementTree represents an XML document as a tree of element nodes. The text
content of the document is stored as the text
and tail
attributes of (This is one of the major differences between ElementTree and
the Document Object Model; in the DOM there are many different types of node,
including TextNode.)
The most commonly used parsing function is parse(), that takes either a
string (assumed to contain a filename) or a file-like object and returns an
ElementTree instance:
from xml.etree import ElementTree as ET
tree = ET.parse('ex-1.xml')
feed = urllib.urlopen(
'http://planet.python.org/rss10.xml')
tree = ET.parse(feed)
Once you have an ElementTree instance, you can
call its getroot()
method to get the root Element node.
There’s also an XML() function that takes a string
literal and returns an Element node (not an
ElementTree). This function provides a
tidy way to incorporate XML fragments, approaching the convenience of an XML
literal:
svg = ET.XML("""<svg width="10px" version="1.0">
</svg>""")
svg.set('height', '320px')
svg.append(elem1)
Кожен елемент XML підтримує деякі методи доступу, подібні до словника, і деякі, подібні до списку. Операції, подібні до словника, використовуються для доступу до значень атрибутів, а операції, подібні до списку, використовуються для доступу до дочірніх вузлів.
Операція |
Результат |
|---|---|
|
Повертає n-й дочірній елемент. |
|
Повертає список від m до n дочірніх елементів. |
|
Повертає кількість дочірніх елементів. |
|
Повертає список дочірніх елементів. |
|
Додає elem2 як дитину. |
|
Вставляє elem2 у вказане місце. |
|
Видаляє n-й дочірній елемент. |
|
Повертає список імен атрибутів. |
|
Повертає значення атрибута name. |
|
Встановлює нове значення для атрибута name. |
|
Отримує словник, що містить атрибути. |
|
Видаляє атрибут name. |
Comments and processing instructions are also represented as Element
nodes. To check if a node is a comment or processing instructions:
if elem.tag is ET.Comment:
...
elif elem.tag is ET.ProcessingInstruction:
...
To generate XML output, you should call the xml.etree.ElementTree.ElementTree.write() method.
Like parse(), it can take either a string or a file-like object:
# Encoding is US-ASCII
tree.write('output.xml')
# Encoding is UTF-8
f = open('output.xml', 'w')
tree.write(f, encoding='utf-8')
(Увага: кодування за замовчуванням, яке використовується для виводу, — ASCII. Для загальної роботи з XML, де ім’я елемента може містити довільні символи Unicode, ASCII не є дуже корисним кодуванням, оскільки воно спричинить виключення, якщо ім’я елемента містить будь-які символи зі значеннями більше 127. Тому найкраще вказати інше кодування, наприклад UTF-8, яке може обробляти будь-який символ Unicode.)
Цей розділ є лише частковим описом інтерфейсів ElementTree. Щоб дізнатися більше, прочитайте офіційну документацію пакета.
Дивись також
- https://web.archive.org/web/20201124024954/http://effbot.org/zone/element-index.htm
Офіційна документація для ElementTree.
Пакет hashlib¶
A new hashlib module, written by Gregory P. Smith, has been added to
replace the md5 and sha modules. hashlib adds support for
additional secure hashes (SHA-224, SHA-256, SHA-384, and SHA-512). When
available, the module uses OpenSSL for fast platform optimized implementations
of algorithms.
The old md5 and sha modules still exist as wrappers around hashlib
to preserve backwards compatibility. The new module’s interface is very close
to that of the old modules, but not identical. The most significant difference
is that the constructor functions for creating new hashing objects are named
differently.
# Old versions
h = md5.md5()
h = md5.new()
# New version
h = hashlib.md5()
# Old versions
h = sha.sha()
h = sha.new()
# New version
h = hashlib.sha1()
# Hash that weren't previously available
h = hashlib.sha224()
h = hashlib.sha256()
h = hashlib.sha384()
h = hashlib.sha512()
# Alternative form
h = hashlib.new('md5') # Provide algorithm as a string
Once a hash object has been created, its methods are the same as before:
update(string) hashes the specified string into the current digest
state, digest() and hexdigest() return the digest value as a binary
string or a string of hex digits, and copy() returns a new hashing object
with the same digest state.
Дивись також
Документація для модуля hashlib.
Пакет sqlite3¶
The pysqlite module (https://www.pysqlite.org), a wrapper for the SQLite embedded
database, has been added to the standard library under the package name
sqlite3.
SQLite — це бібліотека C, яка надає легку дискову базу даних, яка не потребує окремого серверного процесу та дозволяє отримувати доступ до бази даних за допомогою нестандартного варіанту мови запитів SQL. Деякі програми можуть використовувати SQLite для внутрішнього зберігання даних. Також можна створити прототип програми за допомогою SQLite, а потім перенести код у більшу базу даних, таку як PostgreSQL або Oracle.
pysqlite був написаний Герхардом Херінгом і забезпечує інтерфейс SQL, сумісний зі специфікацією DB-API 2.0, описаною PEP 249.
Якщо ви компілюєте вихідні коди Python самостійно, зауважте, що дерево вихідних кодів не містить код SQLite, а містить лише модуль оболонки. Вам потрібно буде встановити бібліотеки та заголовки SQLite перед компіляцією Python, і процес збирання скомпілює модуль, коли необхідні заголовки будуть доступні.
To use the module, you must first create a Connection object that
represents the database. Here the data will be stored in the
/tmp/example file:
conn = sqlite3.connect('/tmp/example')
Ви також можете вказати спеціальну назву :memory:, щоб створити базу даних в RAM.
Once you have a Connection, you can create a Cursor object
and call its execute() method to perform SQL commands:
c = conn.cursor()
# Create table
c.execute('''create table stocks
(date text, trans text, symbol text,
qty real, price real)''')
# Insert a row of data
c.execute("""insert into stocks
values ('2006-01-05','BUY','RHAT',100,35.14)""")
Зазвичай ваші операції SQL повинні використовувати значення зі змінних Python. Ви не повинні складати свій запит за допомогою рядкових операцій Python, оскільки це небезпечно; це робить вашу програму вразливою до SQL-атаки.
Instead, use the DB-API’s parameter substitution. Put ? as a placeholder
wherever you want to use a value, and then provide a tuple of values as the
second argument to the cursor’s execute() method. (Other database modules
may use a different placeholder, such as %s or :1.) For example:
# Never do this -- insecure!
symbol = 'IBM'
c.execute("... where symbol = '%s'" % symbol)
# Do this instead
t = (symbol,)
c.execute('select * from stocks where symbol=?', t)
# Larger example
for t in (('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
('2006-04-06', 'SELL', 'IBM', 500, 53.00),
):
c.execute('insert into stocks values (?,?,?,?,?)', t)
To retrieve data after executing a SELECT statement, you can either treat the
cursor as an iterator, call the cursor’s fetchone() method to retrieve a
single matching row, or call fetchall() to get a list of the matching
rows.
У цьому прикладі використовується форма ітератора:
>>> c = conn.cursor()
>>> c.execute('select * from stocks order by price')
>>> for row in c:
... print row
...
(u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001)
(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
(u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
>>>
Для отримання додаткової інформації про діалект SQL, який підтримує SQLite, див. https://www.sqlite.org.
Дивись також
- https://www.pysqlite.org
Веб-сторінка pysqlite.
- https://www.sqlite.org
Веб-сторінка SQLite; документація описує синтаксис і доступні типи даних для підтримуваного діалекту SQL.
Документація для модуля sqlite3.
- PEP 249 - Специфікація API бази даних 2.0
PEP, написаний Марком-Андре Лембургом.
Пакет wsgiref¶
Інтерфейс шлюзу веб-сервера (WSGI) v1.0 визначає стандартний інтерфейс між веб-серверами та веб-додатками Python і описаний у PEP 333. Пакет wsgiref є еталонною реалізацією специфікації WSGI.
Пакет містить базовий HTTP-сервер, який запускатиме програму WSGI; цей сервер корисний для налагодження, але не призначений для використання у виробництві. Налаштування сервера займає лише кілька рядків коду:
from wsgiref import simple_server
wsgi_app = ...
host = ''
port = 8000
httpd = simple_server.make_server(host, port, wsgi_app)
httpd.serve_forever()
Дивись також
- https://web.archive.org/web/20160331090247/http://wsgi.readthedocs.org/en/latest/
Центральний веб-сайт для ресурсів, пов’язаних з WSGI.
- PEP 333 - Інтерфейс шлюзу веб-сервера Python v1.0
PEP, написаний Філіпом Дж. Ебі.
Зміни збірки та C API¶
Зміни в процесі збирання Python і в API C включають:
Дерево вихідних кодів Python було перетворено з CVS на Subversion у складній процедурі міграції, яка контролювалася та бездоганно виконана Мартіном фон Льовісом. Процедура була розроблена як PEP 347.
Coverity, компанія, яка продає інструмент аналізу вихідного коду під назвою Prevent, надала результати свого дослідження вихідного коду Python. Аналіз виявив близько 60 помилок, які були швидко виправлені. Багато помилок були проблемами повторного підрахунку, які часто траплялися в коді обробки помилок. Перегляньте статистику https://scan.coverity.com.
The largest change to the C API came from PEP 353, which modifies the interpreter to use a
Py_ssize_ttype definition instead of int. See the earlier section PEP 353: використання ssize_t як типу індексу for a discussion of this change.Дизайн компілятора байт-коду значно змінився, більше не генеруючи байт-код шляхом обходу дерева аналізу. Замість цього дерево синтаксичного аналізу перетворюється на абстрактне синтаксичне дерево (або AST), і це абстрактне синтаксичне дерево обходиться для отримання байт-коду.
Код Python може отримати об’єкти AST, використовуючи вбудований
compile()і вказавши_ast.PyCF_ONLY_ASTяк значення параметра flags:from _ast import PyCF_ONLY_AST ast = compile("""a=0 for i in range(10): a += i """, "<string>", 'exec', PyCF_ONLY_AST) assignment = ast.body[0] for_loop = ast.body[1]
No official documentation has been written for the AST code yet, but PEP 339 discusses the design. To start learning about the code, read the definition of the various AST nodes in
Parser/Python.asdl. A Python script reads this file and generates a set of C structure definitions inInclude/Python-ast.h. ThePyParser_ASTFromString()andPyParser_ASTFromFile(), defined inInclude/pythonrun.h, take Python source as input and return the root of an AST representing the contents. This AST can then be turned into a code object byPyAST_Compile(). For more information, read the source code, and then ask questions on python-dev.Код AST був розроблений під керівництвом Джеремі Гілтона та впроваджений (в алфавітному порядку) Бреттом Кенноном, Ніком Когланом, Грантом Едвардсом, Джоном Ересманом, Куртом Кайзером, Нілом Норвітцем, Тімом Пітерсом, Арміном Ріго та Нілом Шеменауером, а також учасниками ряд спринтів AST на конференціях, таких як PyCon.
Було застосовано патч Евана Джонса для obmalloc, вперше описаний у виступі на PyCon DC 2005. Python 2.4 розподіляв невеликі об’єкти на аренах розміром 256 КБ, але ніколи не звільняв арен. За допомогою цього патча Python звільнить арени, коли вони порожні. Чистий ефект полягає в тому, що на деяких платформах, коли ви виділяєте багато об’єктів, використання пам’яті Python може фактично зменшитися, коли ви їх видаляєте, і пам’ять може повертатися до операційної системи. (Реалізовано Еваном Джонсом і перероблено Тімом Пітерсом.)
Зауважте, що ця зміна означає, що модулі розширення повинні бути більш обережними під час розподілу пам’яті. API Python має багато різних функцій для розподілу пам’яті, згрупованих у родини. Наприклад,
PyMem_Malloc(),PyMem_Realloc()іPyMem_Free()є однією сім’єю, яка виділяє необроблену пам’ять, тоді якPyObject_Malloc(), :cPyObject_Realloc()іPyObject_Free()— ще одне сімейство, яке має використовуватися для створення об’єктів Python.Previously these different families all reduced to the platform’s
malloc()andfree()functions. This meant it didn’t matter if you got things wrong and allocated memory with thePyMemfunction but freed it with thePyObjectfunction. With 2.5’s changes to obmalloc, these families now do different things and mismatches will probably result in a segfault. You should carefully test your C extension modules with Python 2.5.Вбудовані типи наборів тепер мають офіційний C API. Викличте
PySet_New()іPyFrozenSet_New(), щоб створити новий набір,PySet_Add()іPySet_Discard(), щоб додати та видалити елементи, і :cPySet_Contains()іPySet_Size()для перевірки стану набору. (Надав Реймонд Геттінгер.)Код C тепер може отримати інформацію про точну версію інтерпретатора Python, викликавши функцію
Py_GetBuildInfo(), яка повертає рядок інформації про збірку, як це:"trunk:45355:45356M, 13 квітня 2006 р., 07 :42:19". (Надав Баррі Варшау.)Two new macros can be used to indicate C functions that are local to the current file so that a faster calling convention can be used.
Py_LOCALdeclares the function as returning a value of the specified type and uses a fast-calling qualifier.Py_LOCAL_INLINEdoes the same thing and also requests the function be inlined. If macroPY_LOCAL_AGGRESSIVEis defined beforepython.his included, a set of more aggressive optimizations are enabled for the module; you should benchmark the results to find out if these optimizations actually make the code faster. (Contributed by Fredrik Lundh at the NeedForSpeed sprint.)PyErr_NewException(name, base, dict)тепер може приймати кортеж базових класів як свій аргумент base. (Надав Георг Брандл.)The
PyErr_Warn()function for issuing warnings is now deprecated in favour ofPyErr_WarnEx(category, message, stacklevel)which lets you specify the number of stack frames separating this function and the caller. A stacklevel of 1 is the function callingPyErr_WarnEx(), 2 is the function above that, and so forth. (Added by Neal Norwitz.)Інтерпретатор CPython все ще написаний на C, але тепер код можна скомпілювати за допомогою компілятора C++ без помилок. (Реалізовано Ентоні Бакстером, Мартіном фон Льовісом, Скіпом Монтанаро.)
The
PyRange_New()function was removed. It was never documented, never used in the core code, and had dangerously lax error checking. In the unlikely case that your extensions were using it, you can replace it by something like the following:range = PyObject_CallFunction((PyObject*) &PyRange_Type, "lll", start, stop, step);
Зміни, що стосуються порту¶
MacOS X (10.3 і вище): динамічне завантаження модулів тепер використовує функцію
dlopen()замість специфічних для MacOS функцій.MacOS X: перемикач
--enable-universalsdkдодано до сценарію configure, який компілює інтерпретатор як універсальний двійковий файл, здатний працювати на процесорах PowerPC і Intel. (Надав Рональд Оуссорен; bpo-2573.)Windows:
.dllбільше не підтримується як розширення імені файлу для модулів розширення..pydтепер є єдиним розширенням імені файлу, яке шукатиметься.
Перенесення на Python 2.5¶
У цьому розділі перераховано описані раніше зміни, які можуть потребувати змін у вашому коді:
ASCII тепер є стандартним кодуванням для модулів. Тепер це синтаксична помилка, якщо модуль містить рядкові літерали з 8-бітовими символами, але не має оголошення кодування. У Python 2.4 це викликало попередження, а не синтаксичну помилку.
Previously, the
gi_frameattribute of a generator was always a frame object. Because of the PEP 342 changes described in section PEP 342: Нові функції генератора, it’s now possible forgi_frameto beNone.Нове попередження,
UnicodeWarning, спрацьовує, коли ви намагаєтеся порівняти рядок Unicode з 8-бітним рядком, який не можна перетворити на Unicode за допомогою стандартного кодування ASCII. Раніше такі порівняння викликали винятокUnicodeDecodeError.Бібліотека: модуль
csvтепер суворіше щодо багаторядкових полів у лапках. Якщо ваші файли містять символи нового рядка, вбудовані в поля, вхідні дані слід розділити на рядки таким чином, щоб символи нового рядка зберігалися.Бібліотека: функція
format()модуляlocaleраніше приймала будь-який рядок, якщо з’являлося не більше одного специфікатора %char. У Python 2.5 аргумент має бути точно одним специфікатором %char без навколишнього тексту.Library: The
pickleandcPicklemodules no longer accept a return value ofNonefrom the__reduce__()method; the method must return a tuple of arguments instead. The modules also no longer accept the deprecated bin keyword parameter.Library: The
SimpleXMLRPCServerandDocXMLRPCServerclasses now have arpc_pathsattribute that constrains XML-RPC operations to a limited set of URL paths; the default is to allow only'/'and'/RPC2'. Settingrpc_pathstoNoneor an empty tuple disables this path checking.C API: Many functions now use
Py_ssize_tinstead of int to allow processing more data on 64-bit machines. Extension code may need to make the same change to avoid warnings and to support 64-bit machines. See the earlier section PEP 353: використання ssize_t як типу індексу for a discussion of this change.C API: The obmalloc changes mean that you must be careful to not mix usage of the
PyMem_*andPyObject_*families of functions. Memory allocated with one family’s*_Mallocmust be freed with the corresponding family’s*_Freefunction.
Подяки¶
Автор хотів би подякувати наступним особам за пропозиції, виправлення та допомогу з різними чернетками цієї статті: Георг Брандл, Нік Коглан, Філіп Дж. Ебі, Ларс Густебель, Раймонд Геттінгер, Ральф В. Гроссе-Кунстлев, Кент Джонсон, Йен Лоу, Мартін фон Льовіс, Фредрік Лунд, Ендрю Макнамара, Скіп Монтанаро, Густаво Німейєр, Пол Прескод, Джеймс Прайор, Майк Ровнер, Скотт Вайкарт, Баррі Варсоу, Томас Воутерс.