Що нового в Python 3.2¶
- Автор:
Raymond Hettinger
This article explains the new features in Python 3.2 as compared to 3.1. Python 3.2 was released on February 20, 2011. It focuses on a few highlights and gives a few examples. For full details, see the Misc/NEWS file.
Дивись також
PEP 392 - Графік випуску Python 3.2
PEP 384: Визначення стабільного ABI¶
У минулому модулі розширення, створені для однієї версії Python, часто не можна було використовувати з іншими версіями Python. Зокрема, у Windows кожен випуск функції Python вимагав перебудови всіх модулів розширення, які потрібно було використовувати. Ця вимога була результатом вільного доступу до внутрішніх елементів інтерпретатора Python, які могли використовувати модулі розширення.
З Python 3.2 стає доступним альтернативний підхід: модулі розширення, які обмежуються обмеженим API (шляхом визначення Py_LIMITED_API), не можуть використовувати багато внутрішніх компонентів, але обмежені набором функцій API, які обіцяють бути стабільними для кількох випусків. Як наслідок, модулі розширення, створені для 3.2 у цьому режимі, також працюватимуть з 3.3, 3.4 тощо. Модулі розширення, які використовують деталі структур пам’яті, все ще можуть бути створені, але їх потрібно буде перекомпілювати для кожного випуску функції.
Дивись також
- PEP 384 - Визначення стабільного ABI
PEP, написаний Мартіном фон Льовісом.
PEP 389: Модуль аналізу командного рядка Argparse¶
Новий модуль для синтаксичного аналізу командного рядка, argparse
, було представлено, щоб подолати обмеження optparse
, які не забезпечували підтримку позиційних аргументів (не лише параметрів), підкоманд, необхідних параметрів та інших поширених шаблонів визначення та перевірки параметрів.
Цей модуль уже мав широкий успіх у спільноті як сторонній модуль. Оскільки модуль argparse
є більш повнофункціональним, ніж його попередник, він тепер є кращим модулем для обробки командного рядка. Старіший модуль все ще залишається доступним через значну кількість застарілого коду, який залежить від нього.
Ось анотований приклад синтаксичного аналізатора, який показує такі функції, як обмеження результатів набором варіантів, визначення metavar на екрані довідки, перевірка наявності одного чи кількох позиційних аргументів і створення необхідної опції:
import argparse
parser = argparse.ArgumentParser(
description = 'Manage servers', # main description for help
epilog = 'Tested on Solaris and Linux') # displayed after help
parser.add_argument('action', # argument name
choices = ['deploy', 'start', 'stop'], # three allowed values
help = 'action on each target') # help msg
parser.add_argument('targets',
metavar = 'HOSTNAME', # var name used in help msg
nargs = '+', # require one or more targets
help = 'url for target machines') # help msg explanation
parser.add_argument('-u', '--user', # -u or --user option
required = True, # make it a required argument
help = 'login as user')
Приклад виклику синтаксичного аналізатора за командним рядком:
>>> cmd = 'deploy sneezy.example.com sleepy.example.com -u skycaptain'
>>> result = parser.parse_args(cmd.split())
>>> result.action
'deploy'
>>> result.targets
['sneezy.example.com', 'sleepy.example.com']
>>> result.user
'skycaptain'
Приклад автоматично створеної довідки парсера:
>>> parser.parse_args('-h'.split())
usage: manage_cloud.py [-h] -u USER
{deploy,start,stop} HOSTNAME [HOSTNAME ...]
Manage servers
positional arguments:
{deploy,start,stop} action on each target
HOSTNAME url for target machines
optional arguments:
-h, --help show this help message and exit
-u USER, --user USER login as user
Tested on Solaris and Linux
Особливо приємною функцією argparse
є можливість визначати підпарсери, кожен зі своїми власними шаблонами аргументів і довідкою:
import argparse
parser = argparse.ArgumentParser(prog='HELM')
subparsers = parser.add_subparsers()
parser_l = subparsers.add_parser('launch', help='Launch Control') # first subgroup
parser_l.add_argument('-m', '--missiles', action='store_true')
parser_l.add_argument('-t', '--torpedos', action='store_true')
parser_m = subparsers.add_parser('move', help='Move Vessel', # second subgroup
aliases=('steer', 'turn')) # equivalent names
parser_m.add_argument('-c', '--course', type=int, required=True)
parser_m.add_argument('-s', '--speed', type=int, default=0)
$ ./helm.py --help # top level help (launch and move)
$ ./helm.py launch --help # help for launch options
$ ./helm.py launch --missiles # set missiles=True and torpedos=False
$ ./helm.py steer --course 180 --speed 5 # set movement parameters
Дивись також
- PEP 389 - Новий модуль аналізу командного рядка
PEP, написаний Стівеном Бетардом.
Оновлення коду optparse для детальної інформації про відмінності від optparse
.
PEP 391: Конфігурація на основі словника для журналювання¶
The logging
module provided two kinds of configuration, one style with
function calls for each option or another style driven by an external file saved
in a configparser
format. Those options did not provide the flexibility
to create configurations from JSON or YAML files, nor did they support
incremental configuration, which is needed for specifying logger options from a
command line.
Щоб підтримувати більш гнучкий стиль, модуль тепер пропонує logging.config.dictConfig()
для визначення конфігурації журналювання за допомогою простих словників Python. Опції конфігурації включають засоби форматування, обробники, фільтри та реєстратори. Ось робочий приклад словника конфігурації:
{"version": 1,
"formatters": {"brief": {"format": "%(levelname)-8s: %(name)-15s: %(message)s"},
"full": {"format": "%(asctime)s %(name)-15s %(levelname)-8s %(message)s"}
},
"handlers": {"console": {
"class": "logging.StreamHandler",
"formatter": "brief",
"level": "INFO",
"stream": "ext://sys.stdout"},
"console_priority": {
"class": "logging.StreamHandler",
"formatter": "full",
"level": "ERROR",
"stream": "ext://sys.stderr"}
},
"root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}
Якщо цей словник зберігається у файлі під назвою conf.json
, його можна завантажити та викликати за допомогою такого коду:
>>> import json, logging.config
>>> with open('conf.json') as f:
... conf = json.load(f)
...
>>> logging.config.dictConfig(conf)
>>> logging.info("Transaction completed normally")
INFO : root : Transaction completed normally
>>> logging.critical("Abnormal termination")
2011-02-17 11:14:36,694 root CRITICAL Abnormal termination
Дивись також
- PEP 391 - Конфігурація для журналювання на основі словника
PEP, написаний Вінаєм Саджипом.
PEP 3148: модуль concurrent.futures
¶
Код для створення паралелізму та керування ним збирається в новому просторі імен верхнього рівня concurrent. Його першим членом є пакет futures, який забезпечує єдиний інтерфейс високого рівня для керування потоками та процесами.
Дизайн для concurrent.futures
був натхненний пакетом java.util.concurrent. У цій моделі запущений виклик і його результат представлені об’єктом Future
, який абстрагує функції, спільні для потоків, процесів і віддалених викликів процедур. Цей об’єкт підтримує перевірки статусу (запущено або виконано), тайм-аути, скасування, додавання зворотних викликів і доступ до результатів або винятків.
Основною пропозицією нового модуля є пара класів виконавців для запуску викликів і керування ними. Мета виконавців — спростити використання існуючих інструментів для здійснення паралельних викликів. Вони економлять зусилля, необхідні для налаштування пулу ресурсів, запуску викликів, створення черги результатів, додавання обробки тайм-ауту та обмеження загальної кількості потоків, процесів або віддалених викликів процедур.
В ідеалі кожна програма має спільно використовувати одного виконавця для кількох компонентів, щоб можна було централізовано керувати обмеженнями процесів і потоків. Це вирішує проблему проектування, яка виникає, коли кожен компонент має власну конкуруючу стратегію управління ресурсами.
Обидва класи мають спільний інтерфейс із трьома методами: submit()
для планування виклику та повернення об’єкта Future
; map()
для планування багатьох асинхронних викликів одночасно та shutdown()
для звільнення ресурсів. Цей клас є context manager і може використовуватися в операторі with
, щоб гарантувати автоматичне звільнення ресурсів після завершення виконання незавершених ф’ючерсів.
Простий приклад ThreadPoolExecutor
— це запуск чотирьох паралельних потоків для копіювання файлів:
import concurrent.futures, shutil
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as e:
e.submit(shutil.copy, 'src1.txt', 'dest1.txt')
e.submit(shutil.copy, 'src2.txt', 'dest2.txt')
e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
e.submit(shutil.copy, 'src3.txt', 'dest4.txt')
Дивись також
- PEP 3148 - Ф’ючерси - асинхронне виконання обчислень
PEP, написаний Браяном Квінланом.
Код для потокової паралельної URL-адреси читає, приклад використання потоків для отримання кількох веб-сторінок паралельно.
Код для паралельного обчислення простих чисел, приклад, що демонструє ProcessPoolExecutor
.
PEP 3147: Каталоги сховищ PYC¶
Схема Python для кешування байт-коду у файлах .pyc погано працювала в середовищах із кількома інтерпретаторами Python. Якщо один інтерпретатор зустріне кешований файл, створений іншим інтерпретатором, він перекомпілює джерело та перезапише кешований файл, таким чином втрачаючи переваги кешування.
Питання «бій pyc» стало більш помітним, оскільки дистрибутиви Linux стали звичайними для доставки з декількома версіями Python. Ці конфлікти також виникають з альтернативами CPython, такими як Unladen Swallow.
Щоб вирішити цю проблему, механізм імпорту Python було розширено для використання різних імен файлів для кожного інтерпретатора. Замість того, щоб Python 3.2, Python 3.3 і Unladen Swallow змагалися за файл під назвою «mymodule.pyc», тепер вони шукатимуть «mymodule.cpython-32.pyc», «mymodule.cpython-33.pyc» і «mymodule». .unladen10.pyc». І щоб усі ці нові файли не захаращували вихідні каталоги, файли pyc тепер зібрані в каталозі «__pycache__», який зберігається в каталозі пакетів.
Крім імен файлів і цільових каталогів, нова схема має кілька аспектів, які бачать програмісти:
Імпортовані модулі тепер мають атрибут
__cached__
, який зберігає назву фактичного файлу, який було імпортовано:>>> import collections >>> collections.__cached__ 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
Тег, унікальний для кожного інтерпретатора, доступний з модуля
imp
:>>> import imp >>> imp.get_tag() 'cpython-32'
Сценарії, які намагаються вивести назву вихідного файлу з імпортованого файлу, тепер мають бути розумнішими. Більше недостатньо просто видалити букву «c» із імені файлу «.pyc». Замість цього використовуйте нові функції в модулі
imp
:>>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc') 'c:/py32/lib/collections.py' >>> imp.cache_from_source('c:/py32/lib/collections.py') 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
Модулі
py_compile
іcompileall
оновлено, щоб відобразити нову угоду про іменування та цільовий каталог. Виклик compileall у командному рядку має нові параметри:-i
для вказівки списку файлів і каталогів для компіляції та-b
, який змушує файли байт-коду записуватися в їх старе розташування, а не в __pycache__.The
importlib.abc
module has been updated with new abstract base classes for loading bytecode files. The obsolete ABCs,PyLoader
andPyPycLoader
, have been deprecated (instructions on how to stay Python 3.1 compatible are included with the documentation).
Дивись також
- PEP 3147 - Каталоги репозиторіїв PYC
PEP, автор Баррі Варшау.
PEP 3149: файли .so з тегами версії ABI¶
Каталог сховища PYC дозволяє одночасно розміщувати кілька файлів кешу байт-кодів. Цей PEP реалізує подібний механізм для файлів спільних об’єктів, надаючи їм загальний каталог і окремі імена для кожної версії.
Загальний каталог є «pyshared», а назви файлів відрізняються ідентифікацією реалізації Python (наприклад, CPython, PyPy, Jython тощо), номерами основної та другорядної версій і необов’язковими прапорцями збірки (наприклад, «d» для debug, «m» для pymalloc, «u» для широкого юнікоду). Для довільного пакета «foo» ви можете побачити ці файли, коли встановлено дистрибутивний пакет:
/usr/share/pyshared/foo.cpython-32m.so
/usr/share/pyshared/foo.cpython-33md.so
У самому Python теги доступні з функцій у модулі sysconfig
:
>>> import sysconfig
>>> sysconfig.get_config_var('SOABI') # find the version tag
'cpython-32mu'
>>> sysconfig.get_config_var('EXT_SUFFIX') # find the full filename extension
'.cpython-32mu.so'
Дивись також
- PEP 3149 - файли .so з тегами версії ABI
PEP, автор Баррі Варшау.
PEP 3333: Інтерфейс шлюзу веб-сервера Python v1.0.1¶
Цей інформаційний PEP пояснює, як протокол WSGI має обробляти проблеми з байтами/текстом. Проблема полягає в тому, що обробку рядків у Python 3 найзручніше обробляти за допомогою типу str
, хоча сам протокол HTTP орієнтований на байти.
PEP розрізняє так звані власні рядки, які використовуються для заголовків запитів/відповідей і метаданих, від байтових рядків, які використовуються для тіл запитів і відповідей.
The native strings are always of type str
but are restricted to code
points between U+0000 through U+00FF which are translatable to bytes using
Latin-1 encoding. These strings are used for the keys and values in the
environment dictionary and for response headers and statuses in the
start_response()
function. They must follow RFC 2616 with respect to
encoding. That is, they must either be ISO-8859-1 characters or use
RFC 2047 MIME encoding.
Для розробників, які портують програми WSGI з Python 2, ось основні моменти:
Якщо програма вже використовувала рядки для заголовків у Python 2, змінювати не потрібно.
Якщо замість цього програма закодувала вихідні заголовки або декодувала вхідні заголовки, тоді заголовки потрібно буде повторно закодувати в Latin-1. Наприклад, вихідний заголовок, закодований у utf-8, використовував
h.encode('utf-8')
, тепер потребує конвертації з байтів у власні рядки за допомогоюh.encode('utf-8'). decode('latin-1')
.Values yielded by an application or sent using the
write()
method must be byte strings. Thestart_response()
function and environ must use native strings. The two cannot be mixed.
For server implementers writing CGI-to-WSGI pathways or other CGI-style
protocols, the users must to be able access the environment using native strings
even though the underlying platform may have a different convention. To bridge
this gap, the wsgiref
module has a new function,
wsgiref.handlers.read_environ()
for transcoding CGI variables from
os.environ
into native strings and returning a new dictionary.
Дивись також
- PEP 3333 - Інтерфейс шлюзу веб-сервера Python v1.0.1
PEP, написаний Філіпом Ебі.
Інші зміни мови¶
Деякі менші зміни, внесені до основної мови Python:
Форматування рядка для
format()
іstr.format()
отримало нові можливості для символу форматування #. Раніше для цілих чисел у двійковій, вісімковій чи шістнадцятковій системі виводу ставився префікс «0b», «0o» або «0x» відповідно. Тепер він також може обробляти числа з плаваючою точкою, комплексні та десяткові числа, завдяки чому вивід завжди матиме десяткову крапку, навіть якщо за нею не йде жодна цифра.>>> format(20, '#o') '0o24' >>> format(12.34, '#5.0f') ' 12.'
(Запропоновано Марком Дікінсоном і реалізовано Еріком Смітом у bpo-7094.)
Існує також новий метод
str.format_map()
, який розширює можливості існуючого методуstr.format()
, приймаючи довільні об’єкти mapping. Цей новий метод дає змогу використовувати форматування рядка з будь-яким із багатьох словникових об’єктів Python, таких якdefaultdict
,Shelf
,ConfigParser
, абоdbm
. Це також корисно з власними підкласамиdict
, які нормалізують ключі перед пошуком або надають метод__missing__()
для невідомих ключів:>>> import shelve >>> d = shelve.open('tmp.shl') >>> 'The {project_name} status is {status} as of {date}'.format_map(d) 'The testing project status is green as of February 15, 2011' >>> class LowerCasedDict(dict): ... def __getitem__(self, key): ... return dict.__getitem__(self, key.lower()) >>> lcd = LowerCasedDict(part='widgets', quantity=10) >>> 'There are {QUANTITY} {Part} in stock'.format_map(lcd) 'There are 10 widgets in stock' >>> class PlaceholderDict(dict): ... def __missing__(self, key): ... return '<{}>'.format(key) >>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict()) 'Hello <name>, welcome to <location>'
(Запропоновано Raymond Hettinger і реалізовано Eric Smith у bpo-6081.)
The interpreter can now be started with a quiet option,
-q
, to prevent the copyright and version information from being displayed in the interactive mode. The option can be introspected using thesys.flags
attribute:$ python -q >>> sys.flags sys.flags(debug=0, division_warning=0, inspect=0, interactive=0, optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0, ignore_environment=0, verbose=0, bytes_warning=0, quiet=1)
(Надав Марчін Войдир у bpo-1772833).
The
hasattr()
function works by callinggetattr()
and detecting whether an exception is raised. This technique allows it to detect methods created dynamically by__getattr__()
or__getattribute__()
which would otherwise be absent from the class dictionary. Formerly, hasattr would catch any exception, possibly masking genuine errors. Now, hasattr has been tightened to only catchAttributeError
and let other exceptions pass through:>>> class A: ... @property ... def f(self): ... return 1 // 0 ... >>> a = A() >>> hasattr(a, 'f') Traceback (most recent call last): ... ZeroDivisionError: integer division or modulo by zero
(Виявлено Юрієм Селівановим і виправлено Бенджаміном Петерсоном; bpo-9666.)
str()
числа з плаваючою точкою або комплексного числа тепер збігається з йогоrepr()
. Раніше формаstr()
була коротшою, але це лише викликало плутанину, і тепер вона більше не потрібна, оскільки найкоротша можливаrepr()
відображається за замовчуванням:>>> import math >>> repr(math.pi) '3.141592653589793' >>> str(math.pi) '3.141592653589793'
(Запропоновано та реалізовано Марком Дікінсоном; bpo-9337.)
Об’єкти
memoryview
тепер мають методrelease()
і тепер вони також підтримують протокол керування контекстом. Це дозволяє своєчасно звільнити будь-які ресурси, отримані під час запиту буфера з вихідного об’єкта.>>> with memoryview(b'abcdefgh') as v: ... print(v.tolist()) [97, 98, 99, 100, 101, 102, 103, 104]
(Додав Антуан Пітру; bpo-9757.)
Раніше було заборонено видаляти ім’я з локального простору імен, якщо воно зустрічається як вільна змінна у вкладеному блоці:
def outer(x): def inner(): return x inner() del x
Тепер це дозволено. Пам’ятайте, що ціль речення
except
очищено, тому цей код, який раніше працював з Python 2.6, викликавSyntaxError
з Python 3.1 і тепер знову працює:def f(): def print_error(): print(e) try: something except Exception as e: print_error() # implicit "del e" here
(Див. bpo-4617.)
Struct sequence types are now subclasses of tuple. This means that C structures like those returned by
os.stat()
,time.gmtime()
, andsys.version_info
now work like a named tuple and now work with functions and methods that expect a tuple as an argument. This is a big step forward in making the C structures as flexible as their pure Python counterparts:>>> import sys >>> isinstance(sys.version_info, tuple) True >>> 'Version %d.%d.%d %s(%d)' % sys.version_info 'Version 3.2.0 final(0)'
(Запропоновано Arfrever Frehtes Taifersar Arahesis і реалізовано Бенджаміном Петерсоном у bpo-8413.)
Тепер попередженнями легше керувати за допомогою змінної середовища
PYTHONWARNINGS
як альтернативи використанню-W
у командному рядку:$ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'
(Запропоновано Barry Warsaw і реалізовано Philip Jenvey у bpo-7301.)
Додано нову категорію попереджень
ResourceWarning
. Випускається, коли виявляються потенційні проблеми із споживанням ресурсів або очищенням. За замовчуванням у звичайних збірках випуску його вимкнено, але його можна ввімкнути за допомогою засобів, наданих модулемwarnings
, або в командному рядку.A
ResourceWarning
is issued at interpreter shutdown if thegc.garbage
list isn’t empty, and ifgc.DEBUG_UNCOLLECTABLE
is set, all uncollectable objects are printed. This is meant to make the programmer aware that their code contains object finalization issues.ResourceWarning
також видається, коли file object знищується без явного закриття. Хоча засіб звільнення для такого об’єкта гарантує, що він закриває основний ресурс операційної системи (зазвичай, дескриптор файлу), затримка звільнення об’єкта може спричинити різні проблеми, особливо під Windows. Ось приклад увімкнення попередження з командного рядка:$ python -q -Wdefault >>> f = open("foo", "wb") >>> del f __main__:1: ResourceWarning: unclosed file <_io.BufferedWriter name='foo'>
(Додано Антуаном Пітру та Георгом Брандлом у bpo-10093 та bpo-477863.)
range
objects now support index and count methods. This is part of an effort to make more objects fully implement thecollections.Sequence
abstract base class. As a result, the language will have a more uniform API. In addition,range
objects now support slicing and negative indices, even with values larger thansys.maxsize
. This makes range more interoperable with lists:>>> range(0, 100, 2).count(10) 1 >>> range(0, 100, 2).index(10) 5 >>> range(0, 100, 2)[5] 10 >>> range(0, 100, 2)[0:5] range(0, 10, 2)
(Надано Даніелем Штуцбахом у bpo-9213, Олександром Бєлопольським у bpo-2690 та Ніком Когланом у bpo-10889.)
Вбудовану функцію
callable()
з Py2.x було відроджено. Він надає стислу, зрозумілу альтернативу використанню abstract base class у виразі на зразокisinstance(x, collections.Callable)
:>>> callable(max) True >>> callable(20) False
(Див. bpo-10518.)
Механізм імпорту Python тепер може завантажувати модулі, встановлені в каталогах із символами, відмінними від ASCII, у імені шляху. Це вирішило серйозну проблему з домашніми каталогами для користувачів із символами, відмінними від ASCII, у їхніх іменах користувачів.
(Потрібна велика робота Віктора Стіннера в bpo-9425.)
Нові, покращені та застарілі модулі¶
Стандартна бібліотека Python зазнала значних зусиль з обслуговування та покращення якості.
Найбільшою новиною для Python 3.2 є те, що пакет email
, модуль mailbox
і модулі nntplib
тепер коректно працюють із моделлю байт/текст у Python 3. Вперше , існує правильна обробка повідомлень із змішаним кодуванням.
У стандартній бібліотеці більше уваги приділялося кодуванням і питанням тексту та байтів. Зокрема, під час взаємодії з операційною системою тепер краще обмінюватися даними, відмінними від ASCII, за допомогою кодування Windows MBCS, кодування з урахуванням локалі або UTF-8.
Ще однією важливою перевагою є додавання значно кращої підтримки з’єднань SSL і сертифікатів безпеки.
Крім того, більше класів тепер реалізують context manager для підтримки зручного та надійного очищення ресурсів за допомогою оператора with
.
електронною поштою¶
Зручність використання пакета email
у Python 3 була здебільшого виправлена завдяки значним зусиллям Р. Девіда Мюррея. Проблема полягала в тому, що електронні листи зазвичай читаються та зберігаються у формі bytes
, а не str
тексту, і вони можуть містити кілька кодувань в одному електронному листі. Отже, пакет електронної пошти потрібно було розширити для аналізу та генерації повідомлень електронної пошти у форматі байтів.
Нові функції
message_from_bytes()
іmessage_from_binary_file()
, а також нові класиBytesFeedParser
іBytesParser
дозволяють двійковий код дані повідомлення, які потрібно розібрати в об’єкти моделі.З урахуванням байтів, введених у модель,
get_payload()
за замовчуванням декодує тіло повідомлення, яке має Content-Transfer-Encoding 8bit, використовуючи набір символів, указаний у заголовки MIME та повертає результуючий рядок.Враховуючи байти, введені в модель,
Generator
перетворить тіла повідомлень, які мають Content-Transfer-Encoding 8bit, на 7bit Content-Transfer-Encoding.Заголовки з незакодованими не-ASCII байтами вважаються RFC 2047-кодованими з використанням набору символів unknown-8bit.
Новий клас
BytesGenerator
створює байти як вихідні дані, зберігаючи будь-які незмінені дані, що не належать до ASCII, які були присутні у вхідних даних, використаних для побудови моделі, включаючи тіла повідомлень із Content-Transfer-Encoding з 8bit.Клас
smtplib
SMTP
тепер приймає рядок байтів для аргументу msg для методуsendmail()
і новий методsend_message()
приймає об’єктMessage
і за бажанням може отримати адреси from_addr і to_addrs безпосередньо з об’єкта.
(Запропоновано та реалізовано Р. Девідом Мюрреєм, bpo-4661 і bpo-10321.)
дерево елементів¶
The xml.etree.ElementTree
package and its xml.etree.cElementTree
counterpart have been updated to version 1.3.
Додано кілька нових корисних функцій і методів:
xml.etree.ElementTree.fromstringlist()
, який створює XML-документ із послідовності фрагментівxml.etree.ElementTree.register_namespace()
для реєстрації префікса глобального простору іменxml.etree.ElementTree.tostringlist()
для представлення рядків, включаючи всі підспискиxml.etree.ElementTree.Element.extend()
для додавання послідовності з нуля або більше елементівxml.etree.ElementTree.Element.iterfind()
шукає елемент і піделементиxml.etree.ElementTree.Element.itertext()
створює текстовий ітератор над елементом і його піделементамиxml.etree.ElementTree.TreeBuilder.end()
закриває поточний елементxml.etree.ElementTree.TreeBuilder.doctype()
обробляє декларацію doctype
Два методи застаріли:
xml.etree.ElementTree.getchildren()
uselist(elem)
instead.xml.etree.ElementTree.getiterator()
useElement.iter
instead.
Докладні відомості про оновлення див. у розділі Introducing ElementTree на веб-сайті Фредріка Лунда.
(Надано Florent Xicluna та Fredrik Lundh, bpo-6472.)
functools¶
Модуль
functools
містить новий декоратор для кешування викликів функцій.functools.lru_cache()
може зберігати повторювані запити до зовнішнього ресурсу щоразу, коли очікується, що результати будуть однаковими.Наприклад, додавання декоратора кешування до функції запиту до бази даних може зберегти доступ до бази даних для популярних пошуків:
>>> import functools >>> @functools.lru_cache(maxsize=300) ... def get_phone_number(name): ... c = conn.cursor() ... c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,)) ... return c.fetchone()[0]
>>> for name in user_requests: ... get_phone_number(name) # cached lookup
Щоб допомогти з вибором ефективного розміру кешу, загорнута функція обладнана для відстеження статистики кешу:
>>> get_phone_number.cache_info() CacheInfo(hits=4805, misses=980, maxsize=300, currsize=300)
Якщо таблиця списку телефонів оновлюється, застарілий вміст кешу можна очистити за допомогою:
>>> get_phone_number.cache_clear()
(Contributed by Raymond Hettinger and incorporating design ideas from Jim Baker, Miki Tebeka, and Nick Coghlan; see recipe 498245, recipe 577479, bpo-10586, and bpo-10593.)
The
functools.wraps()
decorator now adds a__wrapped__
attribute pointing to the original callable function. This allows wrapped functions to be introspected. It also copies__annotations__
if defined. And now it also gracefully skips over missing attributes such as__doc__
which might not be defined for the wrapped callable.У наведеному вище прикладі кеш можна видалити, відновивши вихідну функцію:
>>> get_phone_number = get_phone_number.__wrapped__ # uncached function
(Автори Нік Коглан і Терренс Коул; bpo-9567, bpo-3445 і bpo-8814.)
Щоб допомогти писати класи з розширеними методами порівняння, новий декоратор
functools.total_ordering()
використовуватиме існуючі методи рівності та нерівності для заповнення решти методів.Наприклад, введення __eq__ і __lt__ дозволить
total_ordering()
заповнити __le__, __gt__ і __ge__:@total_ordering class Student: def __eq__(self, other): return ((self.lastname.lower(), self.firstname.lower()) == (other.lastname.lower(), other.firstname.lower())) def __lt__(self, other): return ((self.lastname.lower(), self.firstname.lower()) < (other.lastname.lower(), other.firstname.lower()))
За допомогою декоратора total_ordering решта методів порівняння заповнюється автоматично.
(Надав Реймонд Геттінгер.)
Щоб допомогти у перенесенні програм із Python 2, функція
functools.cmp_to_key()
перетворює стару функцію порівняння на сучасну key function:>>> # locale-aware sort order >>> sorted(iterable, key=cmp_to_key(locale.strcoll))
Приклади сортування та короткий посібник із сортування див. у посібнику Sorting HowTo.
(Надав Реймонд Геттінгер.)
itertools¶
Модуль
itertools
має нову функціюaccumulate()
, створену на основі оператора scan APL і функції accumulate Numpy:>>> from itertools import accumulate >>> list(accumulate([8, 2, 50])) [8, 10, 60]
>>> prob_dist = [0.1, 0.4, 0.2, 0.3] >>> list(accumulate(prob_dist)) # cumulative probability distribution [0.1, 0.5, 0.7, 1.0]
Для прикладу використання
accumulate()
див. приклади для випадкового модуля.(Надано Реймондом Геттінгером і враховано пропозиції щодо дизайну Марка Дікінсона.)
колекції¶
Клас
collections.Counter
тепер має дві форми віднімання на місці, наявний оператор -= для насиченого віднімання і новий методsubtract()
для звичайне віднімання. Перший підходить для мультимножин, які мають лише позитивні підрахунки, а другий більше підходить для випадків використання, які дозволяють негативні підрахунки:>>> from collections import Counter >>> tally = Counter(dogs=5, cats=3) >>> tally -= Counter(dogs=2, cats=8) # saturating subtraction >>> tally Counter({'dogs': 3})
>>> tally = Counter(dogs=5, cats=3) >>> tally.subtract(dogs=2, cats=8) # regular subtraction >>> tally Counter({'dogs': 3, 'cats': -5})
(Надав Реймонд Геттінгер.)
Клас
collections.OrderedDict
має новий методmove_to_end()
, який бере наявний ключ і переміщує його на першу чи останню позицію в упорядкованій послідовності.За замовчуванням елемент переміщується на останню позицію. Це еквівалентно оновленню запису за допомогою
od[k] = od.pop(k)
.Операція швидкого переходу до кінця корисна для зміни послідовності записів. Наприклад, упорядкований словник можна використовувати для відстеження порядку доступу шляхом старіння записів від найстаріших до найновіших.
>>> from collections import OrderedDict >>> d = OrderedDict.fromkeys(['a', 'b', 'X', 'd', 'e']) >>> list(d) ['a', 'b', 'X', 'd', 'e'] >>> d.move_to_end('X') >>> list(d) ['a', 'b', 'd', 'e', 'X']
(Надав Реймонд Геттінгер.)
У класі
collections.deque
з’явилися два нові методиcount()
іreverse()
, що робить їх більш доступними для об’єктівlist
:>>> from collections import deque >>> d = deque('simsalabim') >>> d.count('s') 2 >>> d.reverse() >>> d deque(['m', 'i', 'b', 'a', 'l', 'a', 's', 'm', 'i', 's'])
(Надав Реймонд Геттінгер.)
різьблення¶
Модуль threading
має новий клас синхронізації Barrier
для того, щоб кілька потоків чекали, поки всі вони досягнуть спільної точки перешкоди. Бар’єри корисні для забезпечення того, щоб завдання з кількома попередніми умовами не запускалося, доки не будуть виконані всі завдання-попередники.
Бар’єри можуть працювати з довільною кількістю потоків. Це узагальнення Rendezvous, яке визначено лише для двох потоків.
Реалізовані як двофазний циклічний бар’єр, об’єкти Barrier
підходять для використання в циклах. Окремі фази заповнення та виливання гарантують, що всі потоки будуть звільнені (осушені) до того, як будь-який з них зможе повернутися назад і знову увійти в бар’єр. Після кожного циклу бар’єр повністю скидається.
Приклад використання бар’єрів:
from threading import Barrier, Thread
def get_votes(site):
ballots = conduct_election(site)
all_polls_closed.wait() # do not count until all polls are closed
totals = summarize(ballots)
publish(site, totals)
all_polls_closed = Barrier(len(sites))
for site in sites:
Thread(target=get_votes, args=(site,)).start()
У цьому прикладі бар’єр забезпечує виконання правила, згідно з яким голоси не можуть бути підраховані на жодній виборчій дільниці, доки всі виборчі дільниці не будуть закриті. Зверніть увагу, що рішення з бар’єром схоже на рішення з threading.Thread.join()
, але потоки залишаються живими та продовжують виконувати роботу (підсумовуючи бюлетені) після перетину точки бар’єру.
Якщо будь-яке з попередніх завдань може зависати або відкладатися, можна створити бар’єр за допомогою додаткового параметра timeout. Потім, якщо період очікування мине до того, як усі завдання-попередники досягнуть точки бар’єру, усі потоки, що очікують, звільняються та виникає виняток BrokenBarrierError
:
def get_votes(site):
ballots = conduct_election(site)
try:
all_polls_closed.wait(timeout=midnight - time.now())
except BrokenBarrierError:
lockbox = seal_ballots(ballots)
queue.put(lockbox)
else:
totals = summarize(ballots)
publish(site, totals)
У цьому прикладі бар’єр забезпечує більш надійне правило. Якщо деякі виборчі дільниці не закінчуються до опівночі, шлагбаум закінчується, а бюлетені запечатуються та залишаються в черзі для подальшої обробки.
See Barrier Synchronization Patterns for more examples of how barriers can be used in parallel computing. Also, there is a simple but thorough explanation of barriers in The Little Book of Semaphores, section 3.6.
(Надав Крістіян Валур Йонссон із оглядом API Джеффрі Яскіним у bpo-8777.)
дата, час і час¶
Модуль
datetime
має новий типtimezone
, який реалізує інтерфейсtzinfo
шляхом повернення фіксованого зміщення UTC і назви часового поясу. Це полегшує створення об’єктів datetime з урахуванням часового поясу:>>> from datetime import datetime, timezone >>> datetime.now(timezone.utc) datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc) >>> datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z") datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)
Крім того, об’єкти
timedelta
тепер можна помножити наfloat
і розділити на об’єктиfloat
іint
. І об’єктиtimedelta
тепер можуть розділяти один одного.Метод
datetime.date.strftime()
більше не обмежується роками після 1900. Новий підтримуваний діапазон років становить від 1000 до 9999 включно.Whenever a two-digit year is used in a time tuple, the interpretation has been governed by
time.accept2dyear
. The default isTrue
which means that for a two-digit year, the century is guessed according to the POSIX rules governing the%y
strptime format.Starting with Py3.2, use of the century guessing heuristic will emit a
DeprecationWarning
. Instead, it is recommended thattime.accept2dyear
be set toFalse
so that large date ranges can be used without guesswork:>>> import time, warnings >>> warnings.resetwarnings() # remove the default warning filters >>> time.accept2dyear = True # guess whether 11 means 11 or 2011 >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0)) Warning (from warnings module): ... DeprecationWarning: Century info guessed for a 2-digit year. 'Fri Jan 1 12:34:56 2011' >>> time.accept2dyear = False # use the full range of allowable dates >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0)) 'Fri Jan 1 12:34:56 11'
Several functions now have significantly expanded date ranges. When
time.accept2dyear
is false, thetime.asctime()
function will accept any year that fits in a C int, while thetime.mktime()
andtime.strftime()
functions will accept the full range supported by the corresponding operating system functions.
(Надано Олександром Бєлопольським та Віктором Стіннером у bpo-1289118, bpo-5094, bpo-6641, bpo-2706, bpo-1777412, bpo-8013 і bpo-10827.)
математика¶
Модуль math
було оновлено шістьма новими функціями, натхненними стандартом C99.
Функція isfinite()
забезпечує надійний і швидкий спосіб визначення спеціальних значень. Він повертає True
для звичайних чисел і False
для Nan або Infinity:
>>> from math import isfinite
>>> [isfinite(x) for x in (123, 4.56, float('Nan'), float('Inf'))]
[True, True, False, False]
Функція expm1()
обчислює e**x-1
для малих значень x без втрати точності, яка зазвичай супроводжує віднімання майже рівних величин:
>>> from math import expm1
>>> expm1(0.013671875) # more accurate way to compute e**x-1 for a small x
0.013765762467652909
Функція erf()
обчислює інтеграл ймовірності або функцію помилки Гауса. Додатковою функцією помилок, erfc()
, є 1 - erf(x)
:
>>> from math import erf, erfc, sqrt
>>> erf(1.0/sqrt(2.0)) # portion of normal distribution within 1 standard deviation
0.682689492137086
>>> erfc(1.0/sqrt(2.0)) # portion of normal distribution outside 1 standard deviation
0.31731050786291404
>>> erf(1.0/sqrt(2.0)) + erfc(1.0/sqrt(2.0))
1.0
Функція gamma()
є безперервним розширенням функції факториалу. Див. https://en.wikipedia.org/wiki/Gamma_function, щоб дізнатися більше. Оскільки функція пов’язана з факториалами, вона збільшується навіть для малих значень x, тому існує також функція lgamma()
для обчислення натурального логарифма гамма-функції:
>>> from math import gamma, lgamma
>>> gamma(7.0) # six factorial
720.0
>>> lgamma(801.0) # log(800 factorial)
4551.950730698041
(Надав Марк Дікінсон.)
абв¶
Модуль abc
тепер підтримує abstractclassmethod()
і abstractstaticmethod()
.
Ці інструменти дають змогу визначити abstract base class, який потребує реалізації конкретного classmethod()
або staticmethod()
:
class Temperature(metaclass=abc.ABCMeta):
@abc.abstractclassmethod
def from_fahrenheit(cls, t):
...
@abc.abstractclassmethod
def from_celsius(cls, t):
...
(Патч надіслав Даніель Урбан; bpo-5867.)
io¶
io.BytesIO
має новий метод, getbuffer()
, який забезпечує функції, подібні до memoryview()
. Він створює редагований вигляд даних без копіювання. Довільний доступ до буфера та підтримка нотації фрагментів добре підходять для редагування на місці:
>>> REC_LEN, LOC_START, LOC_LEN = 34, 7, 11
>>> def change_location(buffer, record_number, location):
... start = record_number * REC_LEN + LOC_START
... buffer[start: start+LOC_LEN] = location
>>> import io
>>> byte_stream = io.BytesIO(
... b'G3805 storeroom Main chassis '
... b'X7899 shipping Reserve cog '
... b'L6988 receiving Primary sprocket'
... )
>>> buffer = byte_stream.getbuffer()
>>> change_location(buffer, 1, b'warehouse ')
>>> change_location(buffer, 0, b'showroom ')
>>> print(byte_stream.getvalue())
b'G3805 showroom Main chassis '
b'X7899 warehouse Reserve cog '
b'L6988 receiving Primary sprocket'
(Надав Антуан Пітру в bpo-5506.)
reprlib¶
When writing a __repr__()
method for a custom container, it is easy to
forget to handle the case where a member refers back to the container itself.
Python’s builtin objects such as list
and set
handle
self-reference by displaying «…» in the recursive part of the representation
string.
To help write such __repr__()
methods, the reprlib
module has a new
decorator, recursive_repr()
, for detecting recursive calls to
__repr__()
and substituting a placeholder string instead:
>>> class MyList(list):
... @recursive_repr()
... def __repr__(self):
... return '<' + '|'.join(map(repr, self)) + '>'
...
>>> m = MyList('abc')
>>> m.append(m)
>>> m.append('x')
>>> print(m)
<'a'|'b'|'c'|...|'x'>
лісозаготівля¶
Окрім описаної вище конфігурації на основі словника, пакет logging
має багато інших покращень.
Документацію з журналювання було доповнено основним підручником, розширеним підручникомі кулінарною книгою з рецептами журналювання. Ці документи є найшвидшим способом дізнатися про лісозаготівлю.
Функція налаштування logging.basicConfig()
отримала аргумент style для підтримки трьох різних типів форматування рядків. За замовчуванням для традиційного форматування %-formatting встановлено значення «%», можна встановити значення «{» для нового стилю str.format()
або значення «$» для форматування стилю оболонки, яке надає string.Template
. Наступні три конфігурації еквівалентні:
>>> from logging import basicConfig
>>> basicConfig(style='%', format="%(name)s -> %(levelname)s: %(message)s")
>>> basicConfig(style='{', format="{name} -> {levelname} {message}")
>>> basicConfig(style='$', format="$name -> $levelname: $message")
If no configuration is set-up before a logging event occurs, there is now a
default configuration using a StreamHandler
directed to
sys.stderr
for events of WARNING
level or higher. Formerly, an
event occurring before a configuration was set-up would either raise an
exception or silently drop the event depending on the value of
logging.raiseExceptions
. The new default handler is stored in
logging.lastResort
.
Використання фільтрів спрощено. Замість створення об’єкта Filter
предикатом може бути будь-який виклик Python, який повертає True
або False
.
З’явилася низка інших покращень, які додають гнучкості та спрощують налаштування. Перегляньте документацію модуля, щоб отримати повний список змін у Python 3.2.
csv¶
Модуль csv
тепер підтримує новий діалект, unix_dialect
, який застосовує лапки для всіх полів і традиційний стиль Unix із '\n'
як символ закінчення рядка. Зареєстрована діалектна назва unix
.
csv.DictWriter
має новий метод, writeheader()
для запису початкового рядка для документування назв полів:
>>> import csv, sys
>>> w = csv.DictWriter(sys.stdout, ['name', 'dept'], dialect='unix')
>>> w.writeheader()
"name","dept"
>>> w.writerows([
... {'name': 'tom', 'dept': 'accounting'},
... {'name': 'susan', 'dept': 'Salesl'}])
"tom","accounting"
"susan","sales"
(Новий діалект, запропонований Джеєм Телботом у bpo-5975, і новий метод, запропонований Едом Абрахамом у bpo-1537721.)
contextlib¶
Існує новий і трохи приголомшливий інструмент ContextDecorator
, який корисний для створення context manager, який виконує подвійну функцію як декоратор функції.
Для зручності ця нова функціональність використовується contextmanager()
, тому не потрібно докладати додаткових зусиль для підтримки обох ролей.
Основна ідея полягає в тому, що як менеджери контексту, так і декоратори функцій можна використовувати для обгорток до і після дії. Менеджери контексту обгортають групу операторів за допомогою оператора with
, а декоратори функцій обгортають групу операторів, укладених у функцію. Отже, іноді виникає потреба написати обгортку до або після дії, яку можна використовувати в обох ролях.
Наприклад, іноді корисно обернути функції або групи операторів за допомогою реєстратора, який може відстежувати час входу та час виходу. Замість того, щоб писати як декоратор функції, так і менеджер контексту для завдання, contextmanager()
надає обидві можливості в одному визначенні:
from contextlib import contextmanager
import logging
logging.basicConfig(level=logging.INFO)
@contextmanager
def track_entry_and_exit(name):
logging.info('Entering: %s', name)
yield
logging.info('Exiting: %s', name)
Раніше це можна було використовувати лише як контекстний менеджер:
with track_entry_and_exit('widget loader'):
print('Some time consuming activity goes here')
load_widget()
Тепер його можна використовувати і як декоратор:
@track_entry_and_exit('widget loader')
def activity():
print('Some time consuming activity goes here')
load_widget()
Спроба виконувати дві ролі одночасно накладає деякі обмеження на техніку. Менеджери контексту зазвичай мають гнучкість для повернення аргументу, який можна використовувати оператором with
, але немає аналогії для декораторів функцій.
У наведеному вище прикладі немає чистого способу для менеджера контексту track_entry_and_exit повернути примірник журналювання для використання в тілі вкладених операторів.
(Надав Майкл Форд у bpo-9110.)
десятковий і дробовий¶
Марк Дікінсон розробив елегантну та ефективну схему, яка гарантує, що різні типи числових даних матимуть однакове хеш-значення, якщо їхні фактичні значення рівні (bpo-8188):
assert hash(Fraction(3, 2)) == hash(1.5) == \
hash(Decimal("1.5")) == hash(complex(1.5, 0))
Some of the hashing details are exposed through a new attribute,
sys.hash_info
, which describes the bit width of the hash value, the
prime modulus, the hash values for infinity and nan, and the multiplier
used for the imaginary part of a number:
>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003)
An early decision to limit the interoperability of various numeric types has
been relaxed. It is still unsupported (and ill-advised) to have implicit
mixing in arithmetic expressions such as Decimal('1.1') + float('1.1')
because the latter loses information in the process of constructing the binary
float. However, since existing floating point value can be converted losslessly
to either a decimal or rational representation, it makes sense to add them to
the constructor and to support mixed-type comparisons.
Конструктор
decimal.Decimal
тепер приймає об’єктиfloat
безпосередньо, тому більше не потрібно використовувати методfrom_float()
(bpo-8257) .Порівняння змішаних типів тепер повністю підтримуються, тому об’єкти
Decimal
можна безпосередньо порівнювати зfloat
іfractions.Fraction
(bpo-2531 і bpo-8188).
Подібні зміни було внесено до fractions.Fraction
, тому методи from_float()
і from_decimal()
більше не потрібні (bpo-8294):
>>> from decimal import Decimal
>>> from fractions import Fraction
>>> Decimal(1.1)
Decimal('1.100000000000000088817841970012523233890533447265625')
>>> Fraction(1.1)
Fraction(2476979795053773, 2251799813685248)
Another useful change for the decimal
module is that the
Context.clamp
attribute is now public. This is useful in creating
contexts that correspond to the decimal interchange formats specified in IEEE
754 (see bpo-8540).
(Надано Марком Дікінсоном і Реймондом Геттінгером.)
ftp¶
Клас ftplib.FTP
тепер підтримує протокол керування контекстом для безумовного використання винятків socket.error
і закриття з’єднання FTP після завершення:
>>> from ftplib import FTP
>>> with FTP("ftp1.at.proftpd.org") as ftp:
ftp.login()
ftp.dir()
'230 Anonymous login ok, restrictions apply.'
dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 .
dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 ..
dr-xr-xr-x 5 ftp ftp 4096 May 6 10:43 CentOS
dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora
Інші файлоподібні об’єкти, такі як mmap.mmap
і fileinput.input()
також розширили менеджери контексту автоматичного закриття:
with fileinput.input(files=('log1.txt', 'log2.txt')) as f:
for line in f:
process(line)
(Надано Тареком Зіаде та Джампаоло Родола у bpo-4972 та Георгом Брандлом у bpo-8046 та bpo-1286.)
Клас FTP_TLS
тепер приймає параметр context, який є об’єктом ssl.SSLContext
, що дозволяє об’єднувати параметри конфігурації SSL, сертифікати та закриті ключі в єдиний (потенційно довготривалий) структура.
(Надав Джампаоло Родола; bpo-8806.)
відкрити¶
Функції os.popen()
і subprocess.Popen()
тепер підтримують оператори with
для автоматичного закриття дескрипторів файлів.
(Надано Антуаном Пітру та Браяном Кертіном у bpo-7461 та bpo-10554.)
вибрати¶
The select
module now exposes a new, constant attribute,
PIPE_BUF
, which gives the minimum number of bytes which are
guaranteed not to block when select.select()
says a pipe is ready
for writing.
>>> import select
>>> select.PIPE_BUF
512
(Доступно в системах Unix. Патч Себастьєна Сабле в bpo-9862)
gzip і zipfile¶
gzip.GzipFile
тепер реалізує io.BufferedIOBase
abstract base class (крім truncate()
). Він також має метод peek()
і підтримує об’єкти файлів, які не можна шукати, а також об’єкти з нульовим доповненням.
Модуль gzip
також отримує функції compress()
і decompress()
для полегшення стиснення та розпакування в пам’яті. Майте на увазі, що текст має бути закодований як bytes
перед стисненням і розпакуванням:
>>> import gzip
>>> s = 'Three shall be the number thou shalt count, '
>>> s += 'and the number of the counting shall be three'
>>> b = s.encode() # convert to utf-8
>>> len(b)
89
>>> c = gzip.compress(b)
>>> len(c)
77
>>> gzip.decompress(c).decode()[:42] # decompress and convert to text
'Three shall be the number thou shalt count'
(Надано Анандом Б. Піллаєм у bpo-3488; і Антуаном Пітру, Ніром Ейдесом і Браяном Кертіном у bpo-9962, bpo-1675951, bpo-7471 та :issue: «2846».)
Also, the zipfile.ZipExtFile
class was reworked internally to represent
files stored inside an archive. The new implementation is significantly faster
and can be wrapped in an io.BufferedReader
object for more speedups. It
also solves an issue where interleaved calls to read and readline gave the
wrong results.
(Патч надіслано Nir Aides у bpo-7610.)
tarfile¶
Клас TarFile
тепер можна використовувати як менеджер контексту. Крім того, його метод add()
має новий параметр, filter, який контролює, які файли додаються до архіву, і дозволяє редагувати метадані файлу.
Новий параметр фільтр замінює старіший, менш гнучкий параметр exclude, який зараз є застарілим. Якщо вказано, необов’язковий параметр filter має бути аргументом ключового слова (keyword argument). Функція фільтра, надана користувачем, приймає об’єкт TarInfo
і повертає оновлений об’єкт TarInfo
, або якщо вона хоче, щоб файл було виключено, функція може повернути None
:
>>> import tarfile, glob
>>> def myfilter(tarinfo):
... if tarinfo.isfile(): # only save real files
... tarinfo.uname = 'monty' # redact the user name
... return tarinfo
>>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:
... for filename in glob.glob('*.txt'):
... tf.add(filename, filter=myfilter)
... tf.list()
-rw-r--r-- monty/501 902 2011-01-26 17:59:11 annotations.txt
-rw-r--r-- monty/501 123 2011-01-26 17:59:11 general_questions.txt
-rw-r--r-- monty/501 3514 2011-01-26 17:59:11 prion.txt
-rw-r--r-- monty/501 124 2011-01-26 17:59:11 py_todo.txt
-rw-r--r-- monty/501 1399 2011-01-26 17:59:11 semaphore_notes.txt
(Запропоновано Тареком Зіаді та реалізовано Ларсом Густебелем у bpo-6856.)
хешліб¶
Модуль hashlib
має два нові постійні атрибути, які перераховують алгоритми хешування, які гарантовано присутні в усіх реалізаціях, і доступні в поточній реалізації:
>>> import hashlib
>>> hashlib.algorithms_guaranteed
{'sha1', 'sha224', 'sha384', 'sha256', 'sha512', 'md5'}
>>> hashlib.algorithms_available
{'md2', 'SHA256', 'SHA512', 'dsaWithSHA', 'mdc2', 'SHA224', 'MD4', 'sha256',
'sha512', 'ripemd160', 'SHA1', 'MDC2', 'SHA', 'SHA384', 'MD2',
'ecdsa-with-SHA1','md4', 'md5', 'sha1', 'DSA-SHA', 'sha224',
'dsaEncryption', 'DSA', 'RIPEMD160', 'sha', 'MD5', 'sha384'}
(Запропоновано Карлом Чене в bpo-7418.)
аст¶
Модуль ast
має чудовий інструмент загального призначення для безпечної оцінки рядків виразів за допомогою синтаксису літералів Python. Функція ast.literal_eval()
служить безпечною альтернативою вбудованій функції eval()
, якою легко зловживати. Python 3.2 додає літерали bytes
і set
до списку підтримуваних типів: рядки, байти, числа, кортежі, списки, dicts, набори, логічні значення та None
.
>>> from ast import literal_eval
>>> request = "{'req': 3, 'func': 'pow', 'args': (2, 0.5)}"
>>> literal_eval(request)
{'args': (2, 0.5), 'req': 3, 'func': 'pow'}
>>> request = "os.system('do something harmful')"
>>> literal_eval(request)
Traceback (most recent call last):
...
ValueError: malformed node or string: <_ast.Call object at 0x101739a10>
(Реалізовано Бенджаміном Петерсоном і Георгом Брандлом.)
ос¶
Різні операційні системи використовують різні кодування для імен файлів і змінних середовища. Модуль os
надає дві нові функції, fsencode()
і fsdecode()
, для кодування та декодування імен файлів:
>>> import os
>>> filename = 'Sehenswürdigkeiten'
>>> os.fsencode(filename)
b'Sehensw\xc3\xbcrdigkeiten'
Some operating systems allow direct access to encoded bytes in the
environment. If so, the os.supports_bytes_environ
constant will be
true.
Для прямого доступу до закодованих змінних середовища (якщо доступно) використовуйте нову функцію os.getenvb()
або використовуйте os.environb
, яка є байтовою версією os.environ
.
(Надав Віктор Стіннер.)
шутил¶
Функція shutil.copytree()
має дві нові опції:
ignore_dangling_symlinks: коли
symlinks=False
, щоб функція копіювала файл, на який вказує символічне посилання, а не саме символічне посилання. Цей параметр заглушить повідомлення про помилку, якщо файл не існує.copy_function: це виклик, який використовуватиметься для копіювання файлів.
shutil.copy2()
використовується за умовчанням.
(Надав Тарек Зіаде.)
Крім того, модуль shutil
тепер підтримує операції архівування для файлів zip, нестиснутих tar-файлів, tar-файлів gzip і tar-файлів bzip. Існують функції для реєстрації додаткових форматів архівних файлів (таких як стиснуті tar-файли xz або спеціальні формати).
Основними функціями є make_archive()
і unpack_archive()
. За замовчуванням обидва працюють з поточним каталогом (який можна встановити за допомогою os.chdir()
) і будь-якими підкаталогами. Ім’я файлу архіву має бути вказано з повним шляхом. Етап архівування є неруйнівним (оригінальні файли залишаються без змін).
>>> import shutil, pprint
>>> os.chdir('mydata') # change to the source directory
>>> f = shutil.make_archive('/var/backup/mydata',
... 'zip') # archive the current directory
>>> f # show the name of archive
'/var/backup/mydata.zip'
>>> os.chdir('tmp') # change to an unpacking
>>> shutil.unpack_archive('/var/backup/mydata.zip') # recover the data
>>> pprint.pprint(shutil.get_archive_formats()) # display known formats
[('bztar', "bzip2'ed tar-file"),
('gztar', "gzip'ed tar-file"),
('tar', 'uncompressed tar file'),
('zip', 'ZIP file')]
>>> shutil.register_archive_format( # register a new archive format
... name='xz',
... function=xz.compress, # callable archiving function
... extra_args=[('level', 8)], # arguments to the function
... description='xz compression'
... )
(Надав Тарек Зіаде.)
sqlite3¶
Модуль sqlite3
оновлено до версії pysqlite 2.6.0. Він має дві нові можливості.
The
sqlite3.Connection.in_transit
attribute is true if there is an active transaction for uncommitted changes.Методи
sqlite3.Connection.enable_load_extension()
іsqlite3.Connection.load_extension()
дозволяють завантажувати розширення SQLite з файлів «.so». Одним із відомих розширень є розширення повнотекстового пошуку, що поширюється разом із SQLite.
(Надано Р. Девідом Мюрреєм і Шашватом Анандом; bpo-8845.)
html¶
Представлено новий модуль html
лише з однією функцією, escape()
, яка використовується для екранування зарезервованих символів із розмітки HTML:
>>> import html
>>> html.escape('x > 2 && x < 7')
'x > 2 && x < 7'
гніздо¶
Модуль socket
має два нових покращення.
Об’єкти Socket тепер мають метод
detach()
, який переводить сокет у закритий стан без фактичного закриття основного дескриптора файлу. Останній потім можна повторно використовувати для інших цілей. (Додав Антуан Пітру; bpo-8524.)socket.create_connection()
тепер підтримує протокол керування контекстом для безумовного використання винятківsocket.error
і закриття сокета після завершення. (Надав Джампаоло Родола; bpo-9794.)
ssl¶
Модуль ssl
додав низку функцій, щоб задовольнити загальні вимоги до безпечних (зашифрованих, автентифікованих) інтернет-з’єднань:
Новий клас,
SSLContext
, служить контейнером для постійних даних SSL, таких як налаштування протоколу, сертифікати, приватні ключі та різні інші параметри. Він міститьwrap_socket()
для створення SSL-сокета з контексту SSL.A new function,
ssl.match_hostname()
, supports server identity verification for higher-level protocols by implementing the rules of HTTPS (from RFC 2818) which are also suitable for other protocols.The
ssl.wrap_socket()
constructor function now takes a ciphers argument. The ciphers string lists the allowed encryption algorithms using the format described in the OpenSSL documentation.При зв’язуванні з останніми версіями OpenSSL модуль
ssl
тепер підтримує розширення індикації імені сервера для протоколу TLS, дозволяючи кільком «віртуальним хостам» використовувати різні сертифікати на одному IP-порту. Це розширення підтримується лише в режимі клієнта та активується шляхом передачі аргументу server_hostname доssl.SSLContext.wrap_socket()
.До модуля
ssl
додано різні параметри, наприкладOP_NO_SSLv2
, який вимикає небезпечний і застарілий протокол SSLv2.Розширення тепер завантажує всі шифри OpenSSL і алгоритми дайджесту. Якщо деякі сертифікати SSL неможливо перевірити, вони повідомляються як помилка «невідомий алгоритм».
The version of OpenSSL being used is now accessible using the module attributes
ssl.OPENSSL_VERSION
(a string),ssl.OPENSSL_VERSION_INFO
(a 5-tuple), andssl.OPENSSL_VERSION_NUMBER
(an integer).
(Надав Антуан Пітру в bpo-8850, bpo-1589, bpo-8322, bpo-5639, bpo-4870, bpo-8484 та bpo-8321.)
nntp¶
Модуль nntplib
має оновлену реалізацію з кращими байтами та текстовою семантикою, а також більш практичними API. Ці вдосконалення порушують сумісність із версією nntplib у Python 3.1, яка сама по собі була частково нефункціональною.
Також додано підтримку безпечних з’єднань через неявний (з використанням nntplib.NNTP_SSL
) і явний (з використанням nntplib.NNTP.starttls()
) TLS.
(Надано Антуаном Пітру в bpo-9360 та Ендрю Вантом у bpo-1926.)
сертифікати¶
http.client.HTTPSConnection
, urllib.request.HTTPSHandler
і urllib.request.urlopen()
тепер приймають додаткові аргументи, щоб дозволити перевірку сертифіката сервера за набором центрів сертифікації, як рекомендовано для публічного використання HTTPS.
(Додав Антуан Пітру, bpo-9003.)
імапліб¶
Підтримку явного TLS у стандартних підключеннях IMAP4 додано за допомогою нового методу imaplib.IMAP4.starttls
.
(Надано Лоренцо М. Катуччі та Антуаном Пітру, bpo-4471.)
http.client¶
У модулі http.client
було внесено ряд невеликих покращень API. Прості відповіді HTTP 0.9 старого стилю більше не підтримуються, а параметр strict застарів у всіх класах.
Класи HTTPConnection
і HTTPSConnection
тепер мають параметр source_address для кортежу (хост, порт), який вказує, звідки здійснюється HTTP-з’єднання.
До HTTPSConnection
додано підтримку перевірки сертифікатів і віртуальних хостів HTTPS.
Метод request()
для об’єктів підключення допускав необов’язковий аргумент body, щоб file object міг використовуватися для надання вмісту запиту. Зручно те, що аргумент body тепер також приймає об’єкт iterable, якщо він містить явний заголовок Content-Length
. Цей розширений інтерфейс набагато гнучкіший, ніж раніше.
Для встановлення з’єднання HTTPS через проксі-сервер існує новий метод set_tunnel()
, який встановлює хост і порт для тунелювання HTTP-з’єднання.
Щоб відповідати поведінці http.server
, клієнтська бібліотека HTTP тепер також кодує заголовки з кодуванням ISO-8859-1 (Latin-1). Він уже робив це для вхідних заголовків, тому тепер поведінка узгоджена як для вхідного, так і для вихідного трафіку. (Див. роботу Арміна Ронашера в bpo-10980.)
unittest¶
Модуль unittest має ряд удосконалень, які підтримують виявлення тестів для пакетів, спрощені експерименти в інтерактивному запиті, нові методи тестування, покращені діагностичні повідомлення про помилки тестів і кращі назви методів.
The command-line call
python -m unittest
can now accept file paths instead of module names for running specific tests (bpo-10620). The new test discovery can find tests within packages, locating any test importable from the top-level directory. The top-level directory can be specified with the-t
option, a pattern for matching files with-p
, and a directory to start discovery with-s
:$ python -m unittest discover -s my_proj_dir -p _test.py
(Надав Майкл Форд.)
Experimentation at the interactive prompt is now easier because the
unittest.TestCase
class can now be instantiated without arguments:>>> from unittest import TestCase >>> TestCase().assertEqual(pow(2, 3), 8)
(Надав Майкл Форд.)
Модуль
unittest
має два нові методи,assertWarns()
іassertWarnsRegex()
для перевірки того, що певний тип попередження викликано кодом, що тестуєтьсяwith self.assertWarns(DeprecationWarning): legacy_function('XYZ')
(Надав Антуан Пітру, bpo-9754.)
Інший новий метод,
assertCountEqual()
, використовується для порівняння двох ітерацій, щоб визначити, чи є їх кількість елементів рівною (чи однакові елементи присутні з однаковою кількістю входжень незалежно від порядку):def test_anagram(self): self.assertCountEqual('algorithm', 'logarithm')
(Надав Реймонд Геттінгер.)
Основною особливістю модуля unittest є спроба створити значущу діагностику, коли тест не вдається. Якщо це можливо, помилка записується разом із різницею виходу. Це особливо корисно для аналізу файлів журналу невдалих тестів. Однак, оскільки відмінності іноді можуть бути об’ємними, існує новий атрибут
maxDiff
, який встановлює максимальну довжину відображених відмінностей.Крім того, назви методів у модулі зазнали ряду очищень.
For example,
assertRegex()
is the new name forassertRegexpMatches()
which was misnamed because the test usesre.search()
, notre.match()
. Other methods using regular expressions are now named using short form «Regex» in preference to «Regexp» – this matches the names used in other unittest implementations, matches Python’s old name for there
module, and it has unambiguous camel-casing.(Надано Реймондом Геттінгером і реалізовано Еціо Мелотті.)
Щоб покращити узгодженість, деякі давні псевдоніми методів застаріли на користь бажаних імен:
Стара назва
Бажане ім’я
assert_()
assertEquals()
assertNotEquals()
assertAlmostEquals()
assertNotAlmostEquals()
Так само очікується, що методи
TestCase.fail*
, застарілі в Python 3.1, будуть видалені в Python 3.3. Також перегляньте розділ Deprecated aliases в документаціїunittest
.(Надав Еціо Мелотті; bpo-9424.)
The
assertDictContainsSubset()
method was deprecated because it was misimplemented with the arguments in the wrong order. This created hard-to-debug optical illusions where tests likeTestCase().assertDictContainsSubset({'a':1, 'b':2}, {'a':1})
would fail.(Надав Реймонд Геттінгер.)
випадковий¶
Цілочисельні методи в модулі random
тепер краще справляються зі створенням рівномірних розподілів. Раніше вони обчислювали вибірку за допомогою int(n*random())
, яка мала невелике зміщення щоразу, коли n не було ступенем двійки. Тепер вибір робиться з діапазону до наступного ступеня двійки, і вибір зберігається лише тоді, коли він потрапляє в діапазон 0 <= x < n
. Зазначені функції та методи: randrange()
, randint()
, choice()
, shuffle()
і вибірка()
.
(Надав Реймонд Геттінгер; bpo-9025.)
попліб¶
Клас POP3_SSL
тепер приймає параметр context, який є об’єктом ssl.SSLContext
, який дозволяє об’єднувати параметри конфігурації SSL, сертифікати та приватні ключі в єдину (потенційно довговічну) структуру .
(Надав Джампаоло Родола; bpo-8807.)
несиндром¶
asyncore.dispatcher
now provides a
handle_accepted()
method
returning a (sock, addr)
pair which is called when a connection has actually
been established with a new remote endpoint. This is supposed to be used as a
replacement for old handle_accept()
and avoids
the user to call accept()
directly.
(Надав Джампаоло Родола; bpo-6706.)
тимчасовий файл¶
Модуль tempfile
має новий контекстний менеджер, TemporaryDirectory
, який забезпечує легке детерміноване очищення тимчасових каталогів:
with tempfile.TemporaryDirectory() as tmpdirname:
print('created temporary dir:', tmpdirname)
(Надано Нілом Шеменауером і Ніком Когланом; bpo-5178.)
оглядати¶
Модуль
inspect
має нову функціюgetgeneratorstate()
для легкої ідентифікації поточного стану генератора-ітератора:>>> from inspect import getgeneratorstate >>> def gen(): ... yield 'demo' >>> g = gen() >>> getgeneratorstate(g) 'GEN_CREATED' >>> next(g) 'demo' >>> getgeneratorstate(g) 'GEN_SUSPENDED' >>> next(g, None) >>> getgeneratorstate(g) 'GEN_CLOSED'
(Надано Родольфо Екхардтом і Ніком Когланом, bpo-10220.)
Для підтримки пошуку без можливості активації динамічного атрибута модуль
inspect
має нову функціюgetattr_static()
. На відміну відhasattr()
, це справжній пошук лише для читання, який гарантовано не змінює стан під час пошуку:>>> class A: ... @property ... def f(self): ... print('Running') ... return 10 ... >>> a = A() >>> getattr(a, 'f') Running 10 >>> inspect.getattr_static(a, 'f') <property object at 0x1022bd788>
(Надав Майкл Форд.)
pydoc¶
Модуль pydoc
тепер надає значно покращений інтерфейс веб-сервера, а також новий параметр командного рядка -b
для автоматичного відкриття вікна браузера для відображення цього сервера:
$ pydoc3.2 -b
(Надав Рон Адам; bpo-2001.)
дис¶
Модуль dis
отримав дві нові функції для перевірки коду, code_info()
і show_code()
. Обидва надають детальну інформацію про об’єкт коду для наданої функції, методу, рядка вихідного коду або об’єкта коду. Перший повертає рядок, а другий друкує його:
>>> import dis, random
>>> dis.show_code(random.choice)
Name: choice
Filename: /Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/random.py
Argument count: 2
Kw-only arguments: 0
Number of locals: 3
Stack size: 11
Flags: OPTIMIZED, NEWLOCALS, NOFREE
Constants:
0: 'Choose a random element from a non-empty sequence.'
1: 'Cannot choose from an empty sequence'
Names:
0: _randbelow
1: len
2: ValueError
3: IndexError
Variable names:
0: self
1: seq
2: i
Крім того, функція dis()
тепер приймає рядкові аргументи, щоб загальну ідіому dis(compile(s, '', 'eval'))
можна було скоротити до dis(s) )
:
>>> dis('3*x+1 if x%2==1 else x//2')
1 0 LOAD_NAME 0 (x)
3 LOAD_CONST 0 (2)
6 BINARY_MODULO
7 LOAD_CONST 1 (1)
10 COMPARE_OP 2 (==)
13 POP_JUMP_IF_FALSE 28
16 LOAD_CONST 2 (3)
19 LOAD_NAME 0 (x)
22 BINARY_MULTIPLY
23 LOAD_CONST 1 (1)
26 BINARY_ADD
27 RETURN_VALUE
>> 28 LOAD_NAME 0 (x)
31 LOAD_CONST 0 (2)
34 BINARY_FLOOR_DIVIDE
35 RETURN_VALUE
У сукупності ці вдосконалення полегшують вивчення того, як реалізовано CPython, і на власні очі побачити, що робить синтаксис мови під капотом.
(Надав Нік Коглан у bpo-9147.)
dbm¶
All database modules now support the get()
and setdefault()
methods.
(Запропоновано Реєм Алленом у bpo-9523.)
ctypes¶
Новий тип ctypes.c_ssize_t
представляє тип даних C ssize_t
.
сайт¶
Модуль site
має три нові функції, корисні для звітування про деталі певної інсталяції Python.
getsitepackages()
містить список усіх глобальних каталогів пакетів сайту.getuserbase()
повідомляє про базовий каталог користувача, де можуть зберігатися дані.getusersitepackages()
показує шлях до каталогу пакетів сайтів для користувача.
>>> import site
>>> site.getsitepackages()
['/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages',
'/Library/Frameworks/Python.framework/Versions/3.2/lib/site-python',
'/Library/Python/3.2/site-packages']
>>> site.getuserbase()
'/Users/raymondhettinger/Library/Python/3.2'
>>> site.getusersitepackages()
'/Users/raymondhettinger/Library/Python/3.2/lib/python/site-packages'
Зручно те, що деякі функції сайту доступні безпосередньо з командного рядка:
$ python -m site --user-base
/Users/raymondhettinger/.local
$ python -m site --user-site
/Users/raymondhettinger/.local/lib/python3.2/site-packages
(Надав Тарек Зіаде в bpo-6693.)
sysconfig¶
Новий модуль sysconfig
дозволяє легко знаходити шляхи встановлення та змінні конфігурації, які різняться залежно від платформи та встановлення.
Модуль пропонує прості функції доступу до інформації про платформу та версію:
get_platform()
повертає такі значення, як linux-i586 або macosx-10.6-ppc.get_python_version()
повертає рядок версії Python, наприклад «3.2».
Він також надає доступ до шляхів і змінних, що відповідають одній із семи названих схем, які використовує distutils
. До них належать posix_prefix, posix_home, posix_user, nt, nt_user, os2, os2_home:
get_paths()
створює словник, що містить шляхи встановлення для поточної схеми встановлення.get_config_vars()
повертає словник специфічних змінних платформи.
Також є зручний інтерфейс командного рядка:
C:\Python32>python -m sysconfig
Platform: "win32"
Python version: "3.2"
Current installation scheme: "nt"
Paths:
data = "C:\Python32"
include = "C:\Python32\Include"
platinclude = "C:\Python32\Include"
platlib = "C:\Python32\Lib\site-packages"
platstdlib = "C:\Python32\Lib"
purelib = "C:\Python32\Lib\site-packages"
scripts = "C:\Python32\Scripts"
stdlib = "C:\Python32\Lib"
Variables:
BINDIR = "C:\Python32"
BINLIBDEST = "C:\Python32\Lib"
EXE = ".exe"
INCLUDEPY = "C:\Python32\Include"
LIBDEST = "C:\Python32\Lib"
SO = ".pyd"
VERSION = "32"
abiflags = ""
base = "C:\Python32"
exec_prefix = "C:\Python32"
platbase = "C:\Python32"
prefix = "C:\Python32"
projectbase = "C:\Python32"
py_version = "3.2"
py_version_nodot = "32"
py_version_short = "3.2"
srcdir = "C:\Python32"
userbase = "C:\Documents and Settings\Raymond\Application Data\Python"
(Виведено з Distutils Тареком Зіаде.)
pdb¶
Модуль налагоджувача pdb
отримав низку покращень зручності використання:
pdb.py
тепер має опцію-c
, яка виконує команди, подані у файлі сценарію.pdbrc
.Файл сценарію
.pdbrc
може містити командиcontinue
іnext
, які продовжують налагодження.The
Pdb
class constructor now accepts a nosigint argument.Нові команди:
l(list)
,ll(long list)
іsource
для переліку вихідного коду.Нові команди:
display
іundisplay
для показу або приховання значення виразу, якщо воно змінилося.Нова команда:
interact
для запуску інтерактивного інтерпретатора, що містить глобальні та локальні імена, знайдені в поточній області.Точки зупину можна очистити за номером точки зупину.
(Надано Георгом Брандлом, Антоніо Куні та Іллею Сендлером.)
аналізатор конфігурації¶
The configparser
module was modified to improve usability and
predictability of the default parser and its supported INI syntax. The old
ConfigParser
class was removed in favor of SafeConfigParser
which has in turn been renamed to ConfigParser
. Support
for inline comments is now turned off by default and section or option
duplicates are not allowed in a single configuration source.
Конфігураційні аналізатори отримали новий API на основі протоколу відображення:
>>> parser = ConfigParser()
>>> parser.read_string("""
... [DEFAULT]
... location = upper left
... visible = yes
... editable = no
... color = blue
...
... [main]
... title = Main Menu
... color = green
...
... [options]
... title = Options
... """)
>>> parser['main']['color']
'green'
>>> parser['main']['editable']
'no'
>>> section = parser['options']
>>> section['title']
'Options'
>>> section['title'] = 'Options (editable: %(editable)s)'
>>> section['title']
'Options (editable: no)'
Новий API реалізовано поверх класичного API, тому користувацькі підкласи парсерів повинні мати можливість використовувати його без змін.
Тепер можна налаштувати структуру INI-файлу, прийняту аналізаторами конфігурації. Користувачі можуть вказати альтернативні роздільники параметрів/значень і префікси коментарів, змінити назву розділу DEFAULT або змінити синтаксис інтерполяції.
Існує підтримка вбудованої інтерполяції, включаючи додатковий обробник інтерполяції ExtendedInterpolation
:
>>> parser = ConfigParser(interpolation=ExtendedInterpolation())
>>> parser.read_dict({'buildout': {'directory': '/home/ambv/zope9'},
... 'custom': {'prefix': '/usr/local'}})
>>> parser.read_string("""
... [buildout]
... parts =
... zope9
... instance
... find-links =
... ${buildout:directory}/downloads/dist
...
... [zope9]
... recipe = plone.recipe.zope9install
... location = /opt/zope
...
... [instance]
... recipe = plone.recipe.zope9instance
... zope9-location = ${zope9:location}
... zope-conf = ${custom:prefix}/etc/zope.conf
... """)
>>> parser['buildout']['find-links']
'\n/home/ambv/zope9/downloads/dist'
>>> parser['instance']['zope-conf']
'/usr/local/etc/zope.conf'
>>> instance = parser['instance']
>>> instance['zope-conf']
'/usr/local/etc/zope.conf'
>>> instance['zope9-location']
'/opt/zope'
Також було введено низку менших функцій, як-от підтримка визначення кодування в операціях читання, визначення резервних значень для функцій get або читання безпосередньо зі словників і рядків.
(Усі зміни внесено Łukasz Langa.)
urllib.parse¶
Для модуля urllib.parse
було зроблено ряд покращень зручності використання.
Функція urlparse()
тепер підтримує адреси IPv6, як описано в RFC 2732:
>>> import urllib.parse
>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
ParseResult(scheme='http',
netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',
path='/foo/',
params='',
query='',
fragment='')
Функція urldefrag()
тепер повертає named tuple:
>>> r = urllib.parse.urldefrag('http://python.org/about/#target')
>>> r
DefragResult(url='http://python.org/about/', fragment='target')
>>> r[0]
'http://python.org/about/'
>>> r.fragment
'target'
Крім того, функція urlencode()
тепер набагато гнучкіша, вона приймає рядковий або байтовий тип для аргументу query. Якщо це рядок, параметри safe, encoding і error надсилаються до quote_plus()
для кодування:
>>> urllib.parse.urlencode([
... ('type', 'telenovela'),
... ('name', '¿Dónde Está Elisa?')],
... encoding='latin-1')
'type=telenovela&name=%BFD%F3nde+Est%E1+Elisa%3F'
Як описано в Parsing ASCII Encoded Bytes, усі функції urllib.parse
тепер приймають рядки байтів у кодуванні ASCII як вхідні дані, якщо вони не змішуються зі звичайними рядками. Якщо рядки байтів у кодуванні ASCII подано як параметри, типи повернення також будуть рядками байтів у кодуванні ASCII:
>>> urllib.parse.urlparse(b'http://www.python.org:80/about/')
ParseResultBytes(scheme=b'http', netloc=b'www.python.org:80',
path=b'/about/', params=b'', query=b'', fragment=b'')
(Робота Ніка Коглана, Дена Мана та Сентіла Кумарана в bpo-2987, bpo-5468 та bpo-9873.)
поштова скринька¶
Завдяки спільним зусиллям Р. Девіда Мюррея модуль mailbox
було виправлено для Python 3.2. Проблема полягала в тому, що поштова скринька спочатку була розроблена з текстовим інтерфейсом, але повідомлення електронної пошти найкраще представлено за допомогою bytes
, оскільки різні частини повідомлення можуть мати різне кодування.
Рішення використовувало бінарну підтримку пакета email
для аналізу довільних повідомлень електронної пошти. Крім того, рішення вимагало низки змін API.
Як і очікувалося, метод add()
для об’єктів mailbox.Mailbox
тепер приймає двійкове введення.
StringIO
та введення текстового файлу застаріли. Крім того, введення рядка буде невдалим раніше, якщо використовуються символи, відмінні від ASCII. Раніше це не вдавалося, коли електронний лист оброблявся на наступному кроці.
Також є підтримка двійкового виведення. Метод get_file()
тепер повертає файл у бінарному режимі (де раніше він неправильно встановлював файл у текстовому режимі). Існує також новий метод get_bytes()
, який повертає bytes
представлення повідомлення, що відповідає даному ключу.
Все ще можна отримати небінарний вихід за допомогою методу get_string()
старого API, але цей підхід не дуже корисний. Натомість найкраще видобувати повідомлення з об’єкта Message
або завантажувати їх із двійкового введення.
(Надано Р. Девідом Мюрреєм, зусиллями Штеффена Даоде Нурпмезо та початкового патча Віктора Стіннера в bpo-9124.)
turtledemo¶
The demonstration code for the turtle
module was moved from the Demo
directory to main library. It includes over a dozen sample scripts with
lively displays. Being on sys.path
, it can now be run directly
from the command-line:
$ python -m turtledemo
(Переміщено з каталогу Demo Олександром Бєлопольським у bpo-10199.)
Багатопотоковість¶
Механізм серіалізації виконання одночасно запущених потоків Python (загальновідомий як GIL або глобальне блокування інтерпретатора) було переписано. Серед цілей були більш передбачувані інтервали перемикання та зменшення накладних витрат через конфлікт блокувань і кількість наступних системних викликів. Поняття «інтервал перевірки», щоб дозволити перемикання потоків, було залишено та замінено абсолютною тривалістю, вираженою в секундах. Цей параметр можна налаштувати через
sys.setswitchinterval()
. Зараз за замовчуванням 5 мілісекунд.Додаткові відомості про реалізацію можна прочитати в повідомленні списку розсилки python-dev (однак «пріоритетні запити», представлені в цьому повідомленні, не були збережені для включення).
(Надав Антуан Пітру.)
Звичайні та рекурсивні блокування тепер приймають додатковий аргумент timeout для свого методу
acquire()
. (Надав Антуан Пітру; bpo-7316.)Так само
threading.Semaphore.acquire()
також отримав аргумент timeout. (Надав Торстен Ландшофф; bpo-850728.)Регулярне та рекурсивне отримання блокувань тепер може бути перервано сигналами на платформах, які використовують Pthreads. Це означає, що програми Python, які блокуються під час отримання блокувань, можна успішно припинити, багаторазово надсилаючи SIGINT процесу (натиснувши Ctrl+C у більшості оболонок). (Надав Рейд Клекнер; bpo-8844.)
Оптимізації¶
Було додано ряд невеликих покращень продуктивності:
Оптимізатор peephole Python тепер розпізнає шаблони, такі як
x in {1, 2}
як тест на приналежність до набору констант. Оптимізатор перетворюєset
якfrozenset
і зберігає попередньо зібрану константу.Тепер, коли покарання за швидкістю зникло, можна почати писати тести на приналежність за допомогою нотації набору. Цей стиль і семантично зрозумілий, і операційно швидкий:
extension = name.rpartition('.')[2] if extension in {'xml', 'html', 'xhtml', 'css'}: handle(name)
(Патч і додаткові тести надав Дейв Малкольм; bpo-6690).
Серіалізація та десеріалізація даних за допомогою модуля
pickle
тепер у кілька разів швидша.(Надано Александром Вассалотті, Антуаном Пітру та командою Unladen Swallow у bpo-9410 та bpo-3873.)
Алгоритм Timsort, який використовується в
list.sort()
іsorted()
, тепер працює швидше та використовує менше пам’яті під час виклику з key function. Раніше кожен елемент списку обгортався тимчасовим об’єктом, який запам’ятовував значення ключа, пов’язане з кожним елементом. Тепер два масиви ключів і значень сортуються паралельно. Це економить пам’ять, яку споживають обгортки сортування, і економить час, втрачений на делегування порівнянь.(Патч Даніеля Штуцбаха в bpo-9915.)
Продуктивність декодування JSON покращується, а споживання пам’яті зменшується щоразу, коли той самий рядок повторюється для кількох ключів. Крім того, кодування JSON тепер використовує прискорення C, якщо аргумент
sort_keys
має значення true.(Надано Антуаном Пітру в bpo-7451 та Раймондом Геттінгером і Антуаном Пітру в bpo-10314.)
Рекурсивні блокування (створені за допомогою API
threading.RLock()
) тепер мають переваги від реалізації C, яка робить їх такими ж швидкими, як і звичайні блокування, і в 10-15 разів швидшими, ніж їхня попередня реалізація на чистому Python.(Надав Антуан Пітру; bpo-3001.)
The fast-search algorithm in stringlib is now used by the
split()
,rsplit()
,splitlines()
andreplace()
methods onbytes
,bytearray
andstr
objects. Likewise, the algorithm is also used byrfind()
,rindex()
,rsplit()
andrpartition()
.Перетворення цілого числа в рядок тепер працюють з двома «цифрами» одночасно, зменшуючи кількість операцій ділення та модуля.
(bpo-6713, Гавейн Болтон, Марк Дікінсон і Віктор Стіннер.)
There were several other minor optimizations. Set differencing now runs faster
when one operand is much larger than the other (patch by Andress Bennetts in
bpo-8685). The array.repeat()
method has a faster implementation
(bpo-1569291 by Alexander Belopolsky). The BaseHTTPRequestHandler
has more efficient buffering (bpo-3709 by Andrew Schaaf). The
operator.attrgetter()
function has been sped-up (bpo-10160 by
Christos Georgiou). And ConfigParser
loads multi-line arguments a bit
faster (bpo-7113 by Łukasz Langa).
Unicode¶
Python has been updated to Unicode 6.0.0. The update to the standard adds over 2,000 new characters including emoji symbols which are important for mobile phones.
In addition, the updated standard has altered the character properties for two Kannada characters (U+0CF1, U+0CF2) and one New Tai Lue numeric character (U+19DA), making the former eligible for use in identifiers while disqualifying the latter. For more information, see Unicode Character Database Changes.
Кодеки¶
Додано підтримку cp720 арабського кодування DOS (bpo-1616979).
Кодування MBCS більше не ігнорує аргумент обробника помилок. У строгому режимі за замовчуванням він викликає UnicodeDecodeError
, коли зустрічає некодовану послідовність байтів, і UnicodeEncodeError
для некодованого символу.
Кодек MBCS підтримує 'strict'
і 'ignore''
обробники помилок для декодування, 'strict'
і 'replace'
для кодування.
Щоб емулювати кодування Python3.1 MBCS, виберіть обробник 'ignore'
для декодування та 'replace'
обробник для кодування.
У Mac OS X Python декодує аргументи командного рядка за допомогою 'utf-8''
замість кодування локалі.
За замовчуванням tarfile
використовує кодування 'utf-8'
у Windows (замість 'mbcs'
) і 'surrogateescape'
обробник помилок у всіх операційних системах.
Документація¶
Документація продовжує вдосконалюватися.
Таблицю швидких посилань було додано до верхньої частини довгих розділів, таких як Вбудовані функції. У випадку
itertools
посилання супроводжуються таблицями підсумків у стилі шпаргалок, щоб надати огляд і пам’ять без необхідності читати всі документи.У деяких випадках чистий вихідний код Python може бути корисним доповненням до документації, тому тепер багато модулів тепер мають швидкі посилання на останню версію вихідного коду. Наприклад, документація модуля
functools
має швидке посилання вгорі з позначкою:Вихідний код Lib/functools.py.
(Надав Реймонд Хеттінгер; див. обґрунтування.)
Документи тепер містять більше прикладів і рецептів. Зокрема, модуль
re
має великий розділ Приклади регулярних виразів. Так само модульitertools
продовжує оновлюватися новими Рецепти Itertools.Модуль
datetime
тепер має допоміжну реалізацію на чистому Python. Функціональність не змінена. Це просто забезпечує легшу для читання альтернативну реалізацію.(Надав Олександр Бєлопольський у bpo-9528.)
Непідтримуваний каталог
Demo
було видалено. Деякі демонстрації було інтегровано в документацію, деякі переміщено до каталогуTools/demo
, а інші взагалі видалено.(Надав Георг Брандл у bpo-7962.)
ПРОСТОЮЧИЙ¶
Репозиторій коду¶
In addition to the existing Subversion code repository at https://svn.python.org there is now a Mercurial repository at https://hg.python.org/.
Після випуску 3.2 планується перехід на Mercurial як основний репозиторій. Ця розподілена система контролю версій має спростити членам спільноти створення зовнішніх наборів змін і обмін ними. Подробиці див. PEP 385.
Щоб навчитися користуватися новою системою контролю версій, перегляньте Швидкий старт або Посібник із робочих процесів Mercurial.
Зміни збірки та C API¶
Зміни в процесі збирання Python і в API C включають:
Сценарії idle, pydoc і 2to3 тепер інстальовано з суфіксом версії на
make altinstall
(bpo-10679).Функції C, які звертаються до бази даних Unicode, тепер приймають і повертають символи з повного діапазону Unicode, навіть у вузьких збірках Unicode (Py_UNICODE_TOLOWER, Py_UNICODE_ISDECIMAL та інші). Видима відмінність у Python полягає в тому, що
unicodedata.numeric()
тепер повертає правильне значення для великих кодових точок, аrepr()
може вважати більше символів придатними для друку.(Повідомив Bupjoe Lee та виправив Amaury Forgeot D’Arc; bpo-5127.)
Обчислені gotos тепер увімкнено за замовчуванням у підтримуваних компіляторах (які визначаються сценарієм конфігурації). Їх все ще можна вибірково вимкнути, вказавши
--without-computed-gotos
.(Надав Антуан Пітру; bpo-9203.)
Опцію
--with-wctype-functions
видалено. Тепер для всіх функцій використовується вбудована база даних Unicode.(Надано Amaury Forgeot D’Arc; bpo-9210.)
Хеш-значення тепер є значеннями нового типу,
Py_hash_t
, який визначено таким самим розміром, що й покажчик. Раніше вони мали тип long, який у деяких 64-розрядних операційних системах досі має лише 32 біти. У результаті цього виправленняset
іdict
тепер можуть містити більше2**32
записів у збірках із 64-розрядними покажчиками (раніше вони могли збільшуватися до такого розміру але їх продуктивність катастрофічно погіршилася).(Запропоновано Raymond Hettinger і реалізовано Benjamin Peterson; bpo-9778.)
A new macro
Py_VA_COPY
copies the state of the variable argument list. It is equivalent to C99 va_copy but available on all Python platforms (bpo-2443).A new C API function
PySys_SetArgvEx()
allows an embedded interpreter to setsys.argv
without also modifyingsys.path
(bpo-5753).PyEval_CallObject()
is now only available in macro form. The function declaration, which was kept for backwards compatibility reasons, is now removed – the macro was introduced in 1997 (bpo-8276).Існує нова функція
PyLong_AsLongLongAndOverflow()
, яка є аналогомPyLong_AsLongAndOverflow()
. Обидва вони служать для перетворення Pythonint
на рідний тип із фіксованою шириною, забезпечуючи виявлення випадків, коли перетворення не підходить (bpo-7767).Функція
PyUnicode_CompareWithASCIIString()
тепер повертає не дорівнює, якщо рядок Python завершується NUL.Існує нова функція
PyErr_NewExceptionWithDoc()
, яка схожа наPyErr_NewException()
, але дозволяє вказати рядок документа. Це дозволяє виняткам C мати ті самі можливості самодокументування, що й їхні чисті відповідники Python (bpo-7033).При компіляції з опцією
--with-valgrind
розподільник pymalloc буде автоматично вимкнено під час роботи під Valgrind. Це забезпечує покращене виявлення витоку пам’яті під час роботи під Valgrind, водночас користуючись перевагами pymalloc в інший час (bpo-2422).Видалено формат
O?
з функцій PyArg_Parse. Формат більше не використовується і ніколи не був задокументований (bpo-8837).
There were a number of other small changes to the C-API. See the Misc/NEWS file for a complete list.
Also, there were a number of updates to the Mac OS X build, see Mac/BuildScript/README.txt for details. For users running a 32/64-bit build, there is a known problem with the default Tcl/Tk on Mac OS X 10.6. Accordingly, we recommend installing an updated alternative such as ActiveState Tcl/Tk 8.5.9. See https://www.python.org/download/mac/tcltk/ for additional details.
Перенесення на Python 3.2¶
У цьому розділі перераховані раніше описані зміни та інші виправлення помилок, які можуть потребувати змін у вашому коді:
The
configparser
module has a number of clean-ups. The major change is to replace the oldConfigParser
class with long-standing preferred alternativeSafeConfigParser
. In addition there are a number of smaller incompatibilities:Синтаксис інтерполяції тепер перевірено в операціях
get()
іset()
. У стандартній схемі інтерполяції дійсні лише два токени зі знаками відсотка:%(name)s
і%%
, причому останній є екранованим знаком відсотка.Методи
set()
іadd_section()
тепер перевіряють, чи значення є фактичними рядками. Раніше непідтримувані типи могли бути введені ненавмисно.Дубльовані розділи або параметри з одного джерела тепер викликають
DuplicateSectionError
абоDuplicateOptionError
. Раніше дублікати мовчки перезаписували попередній запис.Вбудовані коментарі тепер вимкнено за замовчуванням, тому тепер символ ; можна безпечно використовувати у значеннях.
Коментарі тепер можна робити з відступом. Отже, щоб ; або # з’явилися на початку рядка в багаторядкових значеннях, їх потрібно інтерпольувати. Це запобігає помилковому сприйняттю префіксів коментарів у значеннях як коментарі.
""
тепер є дійсним значенням і більше не перетворюється автоматично на порожній рядок. Для порожніх рядків використовуйте"option ="
у рядку.
Модуль
nntplib
було значно перероблено, що означає, що його API часто несумісні з API 3.1.bytearray
об’єкти більше не можна використовувати як імена файлів; натомість їх слід перетворити наbytes
.The
array.tostring()
andarray.fromstring()
have been renamed toarray.tobytes()
andarray.frombytes()
for clarity. The old names have been deprecated. (See bpo-8990.)Функції
PyArg_Parse*()
:Формат «t#» видалено: замість нього використовуйте «s#» або «s*».
Формати «w» і «w#» видалено: замість них використовуйте «w*».
The
PyCObject
type, deprecated in 3.1, has been removed. To wrap opaque C pointers in Python objects, thePyCapsule
API should be used instead; the new type has a well-defined interface for passing typing safety information and a less complicated signature for calling a destructor.The
sys.setfilesystemencoding()
function was removed because it had a flawed design.Функція та метод
random.seed()
тепер додають початкові значення рядка за допомогою хеш-функції sha512. Щоб отримати доступ до попередньої версії seed для відтворення послідовностей Python 3.1, установіть аргумент version на 1,random.seed(s, version=1)
.The previously deprecated
string.maketrans()
function has been removed in favor of the static methodsbytes.maketrans()
andbytearray.maketrans()
. This change solves the confusion around which types were supported by thestring
module. Now,str
,bytes
, andbytearray
each have their own maketrans and translate methods with intermediate translation tables of the appropriate type.(Надав Георг Брандл; bpo-5675.)
The previously deprecated
contextlib.nested()
function has been removed in favor of a plainwith
statement which can accept multiple context managers. The latter technique is faster (because it is built-in), and it does a better job finalizing multiple context managers when one of them raises an exception:with open('mylog.txt') as infile, open('a.out', 'w') as outfile: for line in infile: if '<critical>' in line: outfile.write(line)
(Надано Георгом Брандлом і Маттіасом Брендстремом; appspot issue 53094.)
struct.pack()
тепер дозволяє лише байти для коду пакета рядківs
. Раніше він приймав текстові аргументи та неявно кодував їх у байти за допомогою UTF-8. Це було проблематично, оскільки воно робило припущення щодо правильного кодування та тому, що кодування змінної довжини може вийти з ладу під час запису в сегмент структури фіксованої довжини.Такий код, як
struct.pack('<6sHHBBB', 'GIF87a', x, y)
слід переписати, щоб використовувати байти замість тексту,struct.pack('<6sHHBBB', b'GIF87a' , x, y)
.(Виявлено Девідом Бізлі та виправлено Віктором Стіннером; bpo-10783.)
Клас
xml.etree.ElementTree
тепер викликає помилкуxml.etree.ElementTree.ParseError
, коли синтаксичний аналіз не вдається. Раніше це викликалоxml.parsers.expat.ExpatError
.Нове, довше значення
str()
у числах з плаваючою точкою може порушити doctests, які покладаються на старий формат виводу.У
subprocess.Popen
стандартним значенням для close_fds тепер єTrue
під Unix; під Windows цеTrue
, якщо для трьох стандартних потоків встановлено значенняNone
,False
інакше. Раніше close_fds за замовчуванням завжди мав значенняFalse
, що створювало проблеми, які важко було вирішити, або змагання, коли дескриптори відкритого файлу потрапляли в дочірній процес.Підтримку застарілого HTTP 0.9 було видалено з
urllib.request
іhttp.client
. Така підтримка все ще присутня на стороні сервера (уhttp.server
).(Надав Антуан Пітру, bpo-10711.)
SSL-сокети в режимі тайм-ауту тепер викликають
socket.timeout
, коли відбувається тайм-аут, а не загальнуSSLError
.(Надав Антуан Пітру, bpo-10272.)
The misleading functions
PyEval_AcquireLock()
andPyEval_ReleaseLock()
have been officially deprecated. The thread-state aware APIs (such asPyEval_SaveThread()
andPyEval_RestoreThread()
) should be used instead.Через ризики безпеці
asyncore.handle_accept()
застаріло, і на його заміну додано нову функціюasyncore.handle_accepted()
.(Надав Джампаоло Родола в bpo-6706.)
Due to the new GIL implementation,
PyEval_InitThreads()
cannot be called beforePy_Initialize()
anymore.