Що нового в Python 3.2¶
- Автор
Raymond Hettinger
This article explains the new features in Python 3.2 as compared to 3.1. 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, написаний Стівеном Бетардом.
Upgrading optparse code для детальної інформації про відмінності від optparse
.
PEP 391: Конфігурація на основі словника для журналювання¶
Модуль logging
надав два види конфігурації: один стиль із викликами функцій для кожного параметра або інший стиль, керований зовнішнім файлом, збереженим у форматі ConfigParser
. Ці параметри не забезпечували гнучкості для створення конфігурацій із файлів JSON або YAML, а також не підтримували інкрементну конфігурацію, яка потрібна для вказівки параметрів журналу з командного рядка.
Щоб підтримувати більш гнучкий стиль, модуль тепер пропонує 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__.Модуль
importlib.abc
було оновлено новими абстрактними базовими класами для завантаження файлів байт-кодів. Застарілі ABC,PyLoader
іPyPycLoader
, стали застарілими (інструкції щодо того, як залишатися сумісними з Python 3.1, включено до документації).
Дивись також
- 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 розрізняє так звані власні рядки, які використовуються для заголовків запитів/відповідей і метаданих, від байтових рядків, які використовуються для тіл запитів і відповідей.
Власні рядки завжди мають тип str
, але обмежені кодовими точками від U+0000 до U+00FF, які можна перевести в байти за допомогою кодування Latin-1. Ці рядки використовуються для ключів і значень у словнику середовища та для заголовків відповідей і статусів у функції start_response()
. Вони повинні відповідати RFC 2616 щодо кодування. Тобто вони мають бути символами ISO-8859-1 або використовувати кодування MIME RFC 2047.
Для розробників, які портують програми WSGI з Python 2, ось основні моменти:
Якщо програма вже використовувала рядки для заголовків у Python 2, змінювати не потрібно.
Якщо замість цього програма закодувала вихідні заголовки або декодувала вхідні заголовки, тоді заголовки потрібно буде повторно закодувати в Latin-1. Наприклад, вихідний заголовок, закодований у utf-8, використовував
h.encode('utf-8')
, тепер потребує конвертації з байтів у власні рядки за допомогоюh.encode('utf-8'). decode('latin-1')
.Значення, отримані програмою або надіслані за допомогою методу
write()
, мають бути рядками байтів. Функціяstart_response()
і середовище мають використовувати рідні рядки. Те двоє не можна змішувати.
Для розробників серверів, які пишуть шляхи CGI-to-WSGI або інші протоколи в стилі CGI, користувачі повинні мати доступ до середовища за допомогою власних рядків, навіть якщо основна платформа може мати іншу конвенцію. Щоб подолати цю прогалину, модуль wsgiref
має нову функцію, wsgiref.handlers.read_environ()
для перекодування змінних CGI з os.environ
у рідні рядки та повернення нового словника.
Дивись також
- 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.)
Інтерпретатор тепер можна запустити з тихою опцією
-q
, щоб запобігти відображенню інформації про авторські права та версію в інтерактивному режимі. Опцію можна перевірити за допомогою атрибутаsys.flags
:$ 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).
Функція
hasattr()
працює, викликаючиgetattr()
і виявляючи, чи виникає виняткова ситуація. Ця техніка дозволяє виявляти методи, створені динамічно__getattr__()
або__getattribute__()
, які інакше були б відсутні у словнику класу. Раніше hasattr перехоплював будь-які винятки, можливо, маскуючи справжні помилки. Тепер hasattr було посилено, щоб перехоплювати лишеAttributeError
і пропускати інші винятки:>>> 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.)
Внутрішній інструмент
structsequence
тепер створює підкласи кортежу. Це означає, що структури C, такі як ті, що повертаютьсяos.stat()
,time.gmtime()
іsys.version_info
тепер працюють як named tuple і тепер працюють з функціями та методами, які очікують кортеж як аргумент. Це великий крок вперед у тому, щоб зробити структури C такими ж гнучкими, як і їхні чисті аналоги Python:>>> 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
, або в командному рядку.ResourceWarning
видається під час завершення роботи інтерпретатора, якщо списокgc.garbage
не порожній, і якщо встановленоgc.DEBUG_UNCOLLECTABLE
, друкуються всі об’єкти, які неможливо зібрати. Це має на меті повідомити програмісту, що його код містить проблеми з фіналізацією об’єктів.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
тепер підтримують методи index і count. Це частина зусиль, щоб більше об’єктів повністю реалізовувалиcollections.Sequence
abstract base class. У результаті мова матиме більш уніфікований API. Крім того, об’єктиrange
тепер підтримують нарізку та негативні індекси, навіть зі значеннями, більшими заsys.maxsize
. Це робить range більш сумісним зі списками:>>> 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.)
дерево елементів¶
Пакет xml.etree.ElementTree
та його аналог xml.etree.cElementTree
оновлено до версії 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()
замість цього використовуйтеlist(elem)
.xml.etree.ElementTree.getiterator()
замість цього використовуйтеElement.iter
.
Докладні відомості про оновлення див. у розділі 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()
(Надано Реймондом Геттінгером і використано дизайнерські ідеї Джима Бейкера, Мікі Тебеки та Ніка Коглана; див. recipe 498245, recipe 577479, bpo-10586 і bpo-10593.)
Декоратор
functools.wraps()
тепер додає атрибут__wrapped__
, який вказує на вихідну функцію, яку можна викликати. Це дозволяє інтроспектувати загорнуті функції. Він також копіює__annotations__
, якщо визначено. І тепер він також витончено пропускає відсутні атрибути, такі як__doc__
, які можуть бути не визначені для загорнутого виклику.У наведеному вище прикладі кеш можна видалити, відновивши вихідну функцію:
>>> 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 включно.Щоразу, коли в кортежі часу використовується двозначний рік, інтерпретація регулюється
time.accept2dyear
. Типовим значенням єTrue
, що означає, що для двозначного року століття вгадується відповідно до правил POSIX, які регулюють формат strptime%y
.Починаючи з Py3.2, використання евристики вгадування століття видасть
DeprecationWarning
. Замість цього рекомендується встановитиtime.accept2dyear
наFalse
, щоб можна було використовувати великі діапазони дат без припущень:>>> 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'
Кілька функцій тепер мають значно розширені діапазони дат. Якщо
time.accept2dyear
має значення false, функціяtime.asctime()
прийматиме будь-який рік, який вміщується в C int, тоді якtime.mktime()
іtime. функції strftime()
прийматимуть повний діапазон, що підтримується відповідними функціями операційної системи.
(Надано Олександром Бєлопольським та Віктором Стіннером у 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¶
Під час написання методу __repr__()
для спеціального контейнера легко забути обробити випадок, коли член повертається до самого контейнера. Вбудовані об’єкти Python, такі як list
і set
обробляють самопосилання, відображаючи «…» у рекурсивній частині рядка представлення.
Щоб полегшити написання таких методів __repr__()
, модуль reprlib
має новий декоратор, recursive_repr()
, для виявлення рекурсивних викликів __repr__()
і заміни заповнювача рядок замість цього:
>>> 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")
Якщо жодна конфігурація не налаштована до того, як відбудеться подія журналювання, тепер існує конфігурація за замовчуванням із використанням StreamHandler
, спрямованого на sys.stderr
для подій рівня WARNING
або вище. Раніше подія, яка відбувалася до налаштування конфігурації, викликала виняток або мовчки видаляла подію залежно від значення logging.raiseExceptions
. Новий обробник за замовчуванням зберігається в 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))
Деякі деталі хешування доступні через новий атрибут sys.hash_info
, який описує бітову ширину хеш-значення, простий модуль, хеш-значення для infinity і nan і множник використовується для уявної частини числа:
>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003)
Попереднє рішення щодо обмеження сумісності різних числових типів було послаблено. Досі не підтримується (і є недоцільним) мати неявне змішування в арифметичних виразах, таких як Decimal('1.1') + float('1.1')
, оскільки останній втрачає інформацію в процесі побудови двійкового float. Однак, оскільки існуюче значення з плаваючою комою можна без втрат перетворити в десяткове чи раціональне представлення, має сенс додати їх до конструктора та підтримувати порівняння змішаного типу.
Конструктор
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)
Ще одна корисна зміна для модуля decimal
полягає в тому, що атрибут Context.clamp
тепер відкритий. Це корисно для створення контекстів, які відповідають десятковим форматам обміну, визначеним у IEEE 754 (див. 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.)
вибрати¶
Модуль select
тепер надає новий постійний атрибут, PIPE_BUF
, який надає мінімальну кількість байтів, які гарантовано не блокуються, коли select.select()
каже труба готова до письма.
>>> 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».)
Крім того, клас zipfile.ZipExtFile
було внутрішньо перероблено для представлення файлів, що зберігаються в архіві. Нова реалізація є значно швидшою та може бути упакована в об’єкт io.BufferedReader
для більшого прискорення. Це також вирішує проблему, через яку чергувані виклики read і readline давали неправильні результати.
(Патч надіслано 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'
Деякі операційні системи дозволяють прямий доступ до закодованих байтів у середовищі. Якщо так, константа os.supports_bytes_environ
буде істинною.
Для прямого доступу до закодованих змінних середовища (якщо доступно) використовуйте нову функцію 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. Він має дві нові можливості.
Атрибут
sqlite3.Connection.in_transit
має значення true, якщо є активна транзакція для незафіксованих змін.Методи
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.Нова функція,
ssl.match_hostname()
, підтримує перевірку ідентичності сервера для протоколів вищого рівня, реалізуючи правила HTTPS (від RFC 2818), які також підходять для інших протоколів.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 неможливо перевірити, вони повідомляються як помилка «невідомий алгоритм».
Версія OpenSSL, яка використовується, тепер доступна за допомогою атрибутів модуля:
ssl.OPENSSL_VERSION
(рядок),ssl.OPENSSL_VERSION_INFO
(кортеж з 5) іssl.OPENSSL_VERSION_NUMBER
(ціле число).
(Надав Антуан Пітру в 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
(Надав Майкл Форд.)
Експериментувати в інтерактивній підказці тепер легше, оскільки екземпляр класу
unittest.case.TestCase
тепер можна створювати без аргументів:>>> 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
, який встановлює максимальну довжину відображених відмінностей.Крім того, назви методів у модулі зазнали ряду очищень.
Наприклад,
assertRegex()
є новою назвою дляassertRegexpMatches()
, яке було неправильно названо, оскільки тест використовуєre.search()
, а неre.match()
. Інші методи, які використовують регулярні вирази, тепер називаються за допомогою короткої форми «Regex» замість «Regexp» — це відповідає назвам, які використовуються в інших реалізаціях unittest, відповідає старій назві Python для модуляre
і має однозначне значення верблюжий кожух.(Надано Реймондом Геттінгером і реалізовано Еціо Мелотті.)
Щоб покращити узгодженість, деякі давні псевдоніми методів застаріли на користь бажаних імен:
Стара назва
Бажане ім’я
assert_()
assertEquals()
assertNotEquals()
assertAlmostEquals()
assertNotAlmostEquals()
Так само очікується, що методи
TestCase.fail*
, застарілі в Python 3.1, будуть видалені в Python 3.3. Також перегляньте розділ Deprecated aliases в документаціїunittest
.(Надав Еціо Мелотті; bpo-9424.)
Метод
assertDictContainsSubset()
визнано застарілим, оскільки його неправильно реалізовано з аргументами в неправильному порядку. Це створювало оптичні ілюзії, які важко налагодити, коли такі тести, якTestCase().assertDictContainsSubset({'a':1, 'b':2}, {'a':1})
не давали результатів.(Надав Реймонд Геттінгер.)
випадковий¶
Цілочисельні методи в модулі 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¶
The pydoc
module now provides a much-improved Web server interface, as
well as a new command-line option -b
to automatically open a browser window
to display that server:
$ 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¶
Усі модулі бази даних тепер підтримують методи get()
і setdefault()
.
(Запропоновано Реєм Алленом у 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
, які продовжують налагодження.Конструктор класу
Pdb
тепер приймає аргумент nosigint.Нові команди:
l(list)
,ll(long list)
іsource
для переліку вихідного коду.Нові команди:
display
іundisplay
для показу або приховання значення виразу, якщо воно змінилося.Нова команда:
interact
для запуску інтерактивного інтерпретатора, що містить глобальні та локальні імена, знайдені в поточній області.Точки зупину можна очистити за номером точки зупину.
(Надано Георгом Брандлом, Антоніо Куні та Іллею Сендлером.)
аналізатор конфігурації¶
Модуль configparser
було змінено, щоб покращити зручність і передбачуваність синтаксичного аналізатора за замовчуванням і його підтримуваного синтаксису INI. Старий клас ConfigParser
було видалено на користь SafeConfigParser
, який, у свою чергу, було перейменовано на ConfigParser
. Підтримку вбудованих коментарів тепер вимкнено за замовчуванням, а дублікати розділів або параметрів не допускаються в одному джерелі конфігурації.
Конфігураційні аналізатори отримали новий 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¶
Демонстраційний код для модуля turtle
переміщено з каталогу Demo до основної бібліотеки. Він містить понад дюжину зразків сценаріїв із яскравими дисплеями. Перебуваючи на sys.path
, тепер його можна запускати безпосередньо з командного рядка:
$ 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.)
Алгоритм швидкого пошуку в stringlib тепер використовується методами
split()
,rsplit()
,splitlines()
іreplace()
дляbytes
, об’єктиbytearray
іstr
. Подібним чином алгоритм також використовуєтьсяrfind()
,rindex()
,rsplit()
іrpartition()
.Перетворення цілого числа в рядок тепер працюють з двома «цифрами» одночасно, зменшуючи кількість операцій ділення та модуля.
(bpo-6713, Гавейн Болтон, Марк Дікінсон і Віктор Стіннер.)
Було ще кілька незначних оптимізацій. Розрізнення наборів тепер працює швидше, коли один операнд значно більший за інший (патч від Андресса Беннетса в bpo-8685). Метод array.repeat()
має швидшу реалізацію (bpo-1569291 від Alexander Belopolsky). BaseHTTPRequestHandler
має більш ефективну буферизацію (bpo-3709 від Ендрю Шаафа). Функцію operator.attrgetter()
було пришвидшено (bpo-10160 від Christos Georgiou). А ConfigParser
завантажує багаторядкові аргументи трохи швидше (bpo-7113 від Ł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 http://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.)
Новий макрос
Py_VA_COPY
копіює стан списку аргументів змінної. Він еквівалентний C99 va_copy, але доступний на всіх платформах Python (bpo-2443).Нова функція C API
PySys_SetArgvEx()
дозволяє вбудованому інтерпретатору встановлюватиsys.argv
без зміниsys.path
(bpo-5753).PyEval_CallObject
тепер доступний лише у формі макросу. Оголошення функції, яке було збережено з міркувань зворотної сумісності, тепер видалено — макрос було представлено в 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¶
У цьому розділі перераховані раніше описані зміни та інші виправлення помилок, які можуть потребувати змін у вашому коді:
Модуль
configparser
має ряд очищення. Основна зміна полягає в заміні старого класуConfigParser
на давню бажану альтернативуSafeConfigParser
. Крім того, існує ряд менших несумісностей:Синтаксис інтерполяції тепер перевірено в операціях
get()
іset()
. У стандартній схемі інтерполяції дійсні лише два токени зі знаками відсотка:%(name)s
і%%
, причому останній є екранованим знаком відсотка.Методи
set()
іadd_section()
тепер перевіряють, чи значення є фактичними рядками. Раніше непідтримувані типи могли бути введені ненавмисно.Дубльовані розділи або параметри з одного джерела тепер викликають
DuplicateSectionError
абоDuplicateOptionError
. Раніше дублікати мовчки перезаписували попередній запис.Вбудовані коментарі тепер вимкнено за замовчуванням, тому тепер символ ; можна безпечно використовувати у значеннях.
Коментарі тепер можна робити з відступом. Отже, щоб ; або # з’явилися на початку рядка в багаторядкових значеннях, їх потрібно інтерпольувати. Це запобігає помилковому сприйняттю префіксів коментарів у значеннях як коментарі.
""
тепер є дійсним значенням і більше не перетворюється автоматично на порожній рядок. Для порожніх рядків використовуйте"option ="
у рядку.
Модуль
nntplib
було значно перероблено, що означає, що його API часто несумісні з API 3.1.bytearray
об’єкти більше не можна використовувати як імена файлів; натомість їх слід перетворити наbytes
.Для ясності
array.tostring()
іarray.fromstring()
перейменовано наarray.tobytes()
іarray.frombytes()
. Старі назви застаріли. (Див. bpo-8990.)Функції
PyArg_Parse*()
:Формат «t#» видалено: замість нього використовуйте «s#» або «s*».
Формати «w» і «w#» видалено: замість них використовуйте «w*».
Тип
PyCObject
, застарілий у версії 3.1, було видалено. Щоб обернути непрозорі вказівники C в об’єкти Python, натомість слід використовувати APIPyCapsule
; новий тип має чітко визначений інтерфейс для передачі інформації про безпеку введення та менш складний підпис для виклику деструктора.Функцію
sys.setfilesystemencoding()
було видалено, оскільки вона мала недоліки.Функція та метод
random.seed()
тепер додають початкові значення рядка за допомогою хеш-функції sha512. Щоб отримати доступ до попередньої версії seed для відтворення послідовностей Python 3.1, установіть аргумент version на 1,random.seed(s, version=1)
.Раніше застарілу функцію
string.maketrans()
було видалено на користь статичних методівbytes.maketrans()
іbytearray.maketrans()
. Ця зміна вирішує плутанину навколо того, які типи підтримувалися модулемstring
. Теперstr
,bytes
іbytearray
кожен має власні методи maketrans і translate із проміжними таблицями перекладу відповідного типу.(Надав Георг Брандл; bpo-5675.)
Раніше застарілу функцію
contextlib.nested()
було вилучено на користь простого оператораwith
, який може приймати кілька менеджерів контексту. Останній метод є швидшим (оскільки він вбудований), і він краще завершує роботу з кількома контекстними менеджерами, коли один із них викликає виняток: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.)
Функції, що вводять в оману
PyEval_AcquireLock()
іPyEval_ReleaseLock()
офіційно визнано застарілими. Замість цього слід використовувати API, що визначають стан потоку (такі якPyEval_SaveThread()
іPyEval_RestoreThread()
).Через ризики безпеці
asyncore.handle_accept()
застаріло, і на його заміну додано нову функціюasyncore.handle_accepted()
.(Надав Джампаоло Родола в bpo-6706.)
Завдяки новій реалізації GIL,
PyEval_InitThreads()
більше не можна викликати доPy_Initialize()
.