Что нового в Python 3.8¶
Редактор: | Raymond Hettinger |
---|
Эта статья объясняет новые возможности в Python 3.8, по сравнению с 3.7. Подробную информацию см. в разделе changelog.
Python 3.8 вышел 14 октября 2019 года.
Резюме - основные моменты выпуска¶
Новые функции¶
Выражения назначения¶
Существует новый синтаксис :=
, который присваивает значения переменным
как части большего выражения. Он ласково известен как «оператор моржей»
благодаря своему сходству с глазами и бивнями моржа.
В этом примере выражение назначения помогает постараться не называть len()
дважды:
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
Аналогичное преимущество возникает при сопоставлении регулярных выражений, когда объекты соответствия необходимы дважды, один раз для проверки того, произошло ли совпадение, а другой - для извлечения подгруппы:
discount = 0.0
if (mo := re.search(r'(\d+)% discount', advertisement)):
discount = float(mo.group(1)) / 100.0
Оператор также полезен с контурами while-loops, которые вычисляют значение для проверки завершения цикла и затем снова нуждаются в том же самом значении в теле цикла:
# Loop over fixed length blocks
while (block := f.read(256)) != '':
process(block)
Другой мотивирующий случай использования возникает в представлениях списка, где значение, вычисленное в условии фильтрации, также необходимо в теле выражения:
[clean_name.title() for name in names
if (clean_name := normalize('NFC', name)) in allowed_names]
Постарайтесь ограничить использование оператора моржей чисткой случаев, которые уменьшают сложность и улучшают удобочитаемость.
Полное описание см. в разделе PEP 572.
(Предоставлено Emily Morehouse в bpo-35224.)
Только позиционные параметры¶
Существует новый синтаксис параметра функции /
, указывающий, что некоторые
параметры функции должны быть указаны позиционно и не могут использоваться в
качестве ключевых аргументов. Это то же обозначение, которое показывает
help()
для функций C, аннотированных с помощью инструмента
Клиники споров Ларри Хастингса.
В следующем примере параметры a и b являются только позиционными, в то время как c или d могут быть позиционными или ключевыми, а e или f должны быть только ключевыми:
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
Ниже приведен действительный вызов:
f(10, 20, 30, d=40, e=50, f=60)
Однако это недопустимые вызовы:
f(10, b=20, c=30, d=40, e=50, f=60) # b не должен быть ключевым аргументом
f(10, 20, 30, 40, 50, f=60) # e должен быть ключевым аргументом
Один из вариантов использования этой нотации заключается в том, что она
позволяет чистым Python функциям полностью эмулировать поведение
существующих C-кодированных функций. Например, встроенная функция divmod()
не
принимает аргументы ключевой:
def divmod(a, b, /):
"Emulate the built in divmod() function"
return (a // b, a % b)
Другой вариант использования - исключить аргументы ключевой, если имя
параметра не полезно. Например, у встроенной функции len()
есть
сигнатура len(obj, /)
. Это исключает неудобные вызовы, такие как:
len(obj='hello') # Ключевой аргумент "obj" ухудшает читабельность
Еще одним преимуществом маркировки параметра как позиционного является то, что
он позволяет изменять имя параметра в будущем без риска нарушения клиентского
код. Например, в модуле statistics
имя параметра dist может быть
изменено в будущем. Это стало возможным с помощью следующей спецификации
функции:
def quantiles(dist, /, *, n=4, method='exclusive')
...
Так как параметры слева от /
не отображаются как возможные ключевые
слова, имена параметров остаются доступными для использования в **kwargs
:
>>> def f(a, b, /, **kwargs):
... print(a, b, kwargs)
...
>>> f(10, 20, a=1, b=2, c=3) # a и b используются двумя способами
10 20 {'a': 1, 'b': 2, 'c': 3}
Это значительно упрощает внедрение функций и методы, который должен принять
произвольные аргументы ключевой. Например, вот выдержка из код в
модуле collections
:
class Counter(dict):
def __init__(self, iterable=None, /, **kwds):
# Примечание "iterable" является возможным ключевым аргументом
Полное описание см. в разделе PEP 570.
(Представлен Pablo Galindo в bpo-36540.)
Параллельный кэш файловой системы для скомпилированных файлов байт-кодов¶
Новая настройка PYTHONPYCACHEPREFIX
(также доступный как
-X
pycache_prefix
) настраивает неявный bytecode кэш, чтобы использовать
отдельное параллельное дерево файловой системы, а не дефолт подкаталоги __pycache__
в
рамках каждого исходного справочника.
О местоположении кэша сообщают в sys.pycache_prefix
(None
указывает на
местоположение по умолчанию в подкаталогах __pycache__
).
(Вклад Carl Meyer в bpo-33499.)
В отладочной сборке используется тот же ABI, что и в версии build¶
Теперь Python использует тот же ABI, независимо от того, встроен ли он в режиме выпуска или отладки. В Unix, когда Python построен в режиме отладки, теперь можно загружать расширения C, построенные в режиме выпуска, и расширения C, построенные с использованием стабильного ABI.
Сборки версий и отладки теперь совместимы с ABI: определение макроса Py_DEBUG
больше не подразумевает макрос Py_TRACE_REFS
, который вводит единственную
несовместимость ABI. Макрос Py_TRACE_REFS
, который добавляет функцию sys.getobjects()
и
переменную окружения PYTHONDUMPREFS
, может быть установлен, используя новый
./configure --with-trace-refs
, строят выбор. (Представлен Victor Stinner в bpo-36465.)
В Unix расширения C больше не связаны с libpython, кроме Android и Cygwin. Для статически связанного Python теперь возможно загрузить построенное использование расширения C общей библиотеки Python. (Представлен Victor Stinner в bpo-21536.)
На Unix, когда Python построен в режиме отладки, импорт теперь также ищет расширения C, собранные в режиме выпуска и для расширений C, собранных со стабильным ABI. (Представлен Victor Stinner в bpo-36722.)
Чтобы встроить Python в приложение, необходимо передать python3-config --libs --embed
новый
параметр --embed
, чтобы получить -lpython3.8
(связать приложение с libpython).
Чтобы поддержать и 3.8 и более старый, попробуйте python3-config --libs --embed
сначала и отступление к python3-config --libs
(без --embed
), если предыдущая команда
терпит неудачу.
Добавьте pkg-config модуль python-3.8-embed
, чтобы включить Python в
применение: pkg-config python-3.8-embed --libs
включает -lpython3.8
.
Чтобы поддержать и 3.8 и более старый, попробуйте pkg-config python-X.Y-embed --libs
сначала и отступление к pkg-config python-X.Y --libs
(без --embed
), если
предыдущая команда терпит неудачу (замените X.Y
версией Python).
С другой стороны, pkg-config python3.8 --libs
больше не содержит -lpython3.8
. Расширения C не
должны быть связаны с libpython (за исключением Android и Cygwin, случаи которых
обрабатываются сценарием); это изменение не совместимо по назначению.
(Представлен Victor Stinner в bpo-36721.)
Поддержка f-строки =
для самостоятельного документирования выражений и отладки¶
Добавлен спецификатор =
к f-строка. Такая f-строка, как
f'{expr=}'
, будет расширена до текста выражения, знака равенства, а затем
представления вычисляемого выражения. Например:
>>> user = 'eric_idle'
>>> member_since = date(1975, 7, 31)
>>> f'{user=} {member_since=}'
"user='eric_idle' member_since=datetime.date(1975, 7, 31)"
Обычные спецификаторы формата f-строк позволяют больше управлять отображением результата выражения:
>>> delta = date.today() - member_since
>>> f'{user=!s} {delta.days=:,d}'
'user=eric_idle delta.days=16,075'
Спецификатор =
отображает выражение целиком, чтобы можно было
отобразить вычисления:
>>> print(f'{theta=} {cos(radians(theta))=:.3f}')
theta=30 cos(radians(theta))=0.866
(Представлен Eric V. Smith и Larry Hastings в bpo-36817.)
PEP 578: Python хуки аудита времени выполнения¶
PEP добавляет Audit Hook и Verified Open Hook. Оба доступны от Python и собственного кода, позволяя заявлениям и фреймворков, написанному в чистом Python код использовать в своих интересах дополнительные уведомления, в то время как также разрешение embedders или системные администраторы, чтобы развернуться строит из Python, где ревизия всегда включается.
Полную информацию см. в разделе PEP 578.
PEP 587: Инициализация конфигурации Python¶
PEP 587 добавляет новый API C, чтобы настроить инициализацию Python, обеспечивающую более прекрасный контроль над целой конфигурацией и лучшую ошибку при сообщении.
Новые структуры:
Новый функции:
PyConfig_Clear()
PyConfig_InitIsolatedConfig()
PyConfig_InitPythonConfig()
PyConfig_Read()
PyConfig_SetArgv()
PyConfig_SetBytesArgv()
PyConfig_SetBytesString()
PyConfig_SetString()
PyPreConfig_InitIsolatedConfig()
PyPreConfig_InitPythonConfig()
PyStatus_Error()
PyStatus_Exception()
PyStatus_Exit()
PyStatus_IsError()
PyStatus_IsExit()
PyStatus_NoMemory()
PyStatus_Ok()
PyWideStringList_Append()
PyWideStringList_Insert()
Py_BytesMain()
Py_ExitStatusException()
Py_InitializeFromConfig()
Py_PreInitialize()
Py_PreInitializeFromArgs()
Py_PreInitializeFromBytesArgs()
Py_RunMain()
Этот PEP также добавляет поля _PyRuntimeState.preconfig
(тип PyPreConfig
) и
PyInterpreterState.config
(тип PyConfig
) к этим внутренним структурам.
PyInterpreterState.config
становится новой ссылочной конфигурацией, заменяя глобальные
переменные конфигурации и другие частные переменные.
Документацию см. в разделе Конфигурация инициализации Python.
Полное описание см. в разделе PEP 587.
(Представлен Victor Stinner в bpo-36763.)
Vectorcall: протокол быстрого вызова для CPython¶
Протокол «vectorcall» добавляется в API Python/C. Предполагается формализовать существующие оптимизации, которые уже были сделаны для различных классы. Этот протокол может использоваться любым типом внутренней линии, реализующим вызываемый абонент.
В настоящее время этот документ носит предварительный характер. Цель состоит в том, чтобы сделать его полностью public в Python 3.9.
Полное описание см. в разделе PEP 590.
(Предоставлено Jeroen Demeyer и Mark Shannon в bpo-36974.)
Pickle протокол 5 с внеполосными буферами данных¶
Когда pickle
- используемый, чтобы передать большие данные между процессами
Python, чтобы использовать в своих интересах многоядерный или
мультимашинная обработка, важно оптимизировать передачу, уменьшая копии памяти,
и возможно применяя пользовательские методы, такие как зависимое от данных сжатие.
Протокол 5 pickle
вводит поддержку внеполосных буферов, где
PEP 3118-compatible данные могут передаваться отдельно от основного потока
pickle, по усмотрению уровня связи.
Полное описание см. в разделе PEP 574.
(Представлен Antoine Pitrou в bpo-36785.)
Другие языковые изменения¶
A
continue
инструкция был незаконным вfinally
клаузуле из-за проблемы с реализацией. В Python 3.8 это ограничение было снято. (Представлен Serhiy Storchaka в bpo-32489.)Типы
bool
,int
иfractions.Fraction
теперь имеютas_integer_ratio()
метод, как вfloat
иdecimal.Decimal
. Это дополнительное расширение API позволяет записыватьnumerator, denominator = x.as_integer_ratio()
и работать в нескольких числовых типах. (Вклад Lisa Roach в bpo-33073 и Raymond Hettinger в bpo-37819.)Конструкторы
int
,float
иcomplex
теперь будут использовать специальный метод__index__()
, если он доступен и соответствующие метод__int__()
,__float__()
или__complex__()
недоступны. (Представлен Serhiy Storchaka в bpo-20092.)Добавлена поддержка
\N{name}
побегов вregular expressions
:>>> notice = 'Copyright © 2019' >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})') >>> int(copyright_year_pattern.search(notice).group(1)) 2019
(Предоставлено Jonathan Eunice и Serhiy Storchaka в bpo-30688.)
Dict и dictviews теперь могут повторяться в обратном порядке вставки с использованием
reversed()
. (Предоставлено Rémi Lapeyre в bpo-33462.Синтаксис, разрешенный для имен ключевой в вызовах функций, был дополнительно ограничен. В частности,
f((keyword)=arg)
больше не допускается. Она никогда не предназначалась для того, чтобы разрешить более чем голое имя в левой части термина уступки аргумента ключевой. (Представлен Benjamin Peterson в bpo-34641.)Обобщенная повторяемая распаковка в
yield
иreturn
инструкции больше не требует круглых скобок приложения. Это приводит синтаксис yield и return в лучшее соответствие с обычным синтаксисом назначения:>>> def parse(family): lastname, *members = family.split() return lastname.upper(), *members >>> parse('simpsons homer marge bart lisa sally') ('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'sally')
(Вклад David Cuthbert и Jordan Chapman в bpo-32117.)
Если запятая пропущена в код, например
[(10, 20) (30, 40)]
, компилятор отображаетSyntaxWarning
с полезным предложением. Это улучшает наличиеTypeError
, указывающего на то, что первый кортеж не был вызываемым. (Представлен Serhiy Storchaka в bpo-15248.)Арифметические операции между подклассы
datetime.date
илиdatetime.datetime
иdatetime.timedelta
объектами теперь возвращают сущность подкласса, а не базовой класс. Это также затрагивает тип возвращения операций, внедрение которых (прямо или косвенно) использует арифметикуdatetime.timedelta
, такую какastimezone()
. (Предоставлено Paul Ganssle в bpo-32417.)Когда Python интерпретатор прерван Ctrl-C (SIGINT), и получающееся исключение
KeyboardInterrupt
не поймано, процесс Python теперь выходит через сигнал SIGINT или с правильным выходом код, таким образом, что процесс запроса может обнаружить, что это умерло из-за Ctrl-C. Оболочки POSIX и Windows используют это для правильного завершения сценариев в интерактивных сеансах. (Вклад Google через Gregory P. Smith в bpo-1054041.)Некоторые расширенные стили программирования требуют обновления объекта
types.CodeType
для существующей функции. Поскольку код объекты являются неизменяемыми, необходимо создать новый код объект, смоделированный на существующем код объекте. При 19 параметрах это было несколько утомительно. Теперь новыйreplace()
метод позволяет создать клон с несколькими измененными параметрами.Вот пример, который изменяет функцию
statistics.mean()
, чтобы препятствовать тому, чтобы параметр data был используемый как аргументом ключевой:>>> from statistics import mean >>> mean(data=[10, 20, 90]) 40 >>> mean.__code__ = mean.__code__.replace(co_posonlyargcount=1) >>> mean(data=[10, 20, 90]) Traceback (most recent call last): ... TypeError: mean() got some positional-only arguments passed as keyword arguments: 'data'
(Представлен Victor Stinner в bpo-37032.)
Для целых чисел трехаргументная форма функции
pow()
теперь позволяет экспоненте быть отрицательной в случае, когда основание относительно простое к модулю. Затем он вычисляет модульную обратную к основанию, когда степень равна-1
, и подходящую степень этой обратной для других отрицательных степеней. Например, чтобы вычислить модульный мультипликативный обратный 38 по модулю 137, запишите:>>> pow(38, -1, 137) 119 >>> 119 * 38 % 137 1
Модульные обратные возникают в решении linear Diophantine equations. Например, чтобы найти целочисленные решения для
4258𝑥 + 147𝑦 = 369
, сначала переписать как4258𝑥 ≡ 369 (mod 147)
затем решить:>>> x = 369 * pow(4258, -1, 147) % 147 >>> y = (4258 * x - 369) // -147 >>> 4258 * x + 147 * y 369
(Представлен Mark Dickinson в bpo-36027.)
Понимания dict синхронизированы с литералами dict, так что ключ вычисляется первым, а значение вторым:
>>> # Dict comprehension >>> cast = {input('role? '): input('actor? ') for i in range(2)} role? King Arthur actor? Chapman role? Black Knight actor? Cleese >>> # Dict literal >>> cast = {input('role? '): input('actor? ')} role? Sir Robin actor? Eric Idle
Гарантированный порядок выполнения полезен с выражениями назначения, поскольку переменные, назначенные в ключевом выражении, будут доступны в выражении значения:
>>> names = ['Martin von Löwis', 'Łukasz Langa', 'Walter Dörwald'] >>> {(n := normalize('NFC', name)).casefold() : n for name in names} {'martin von löwis': 'Martin von Löwis', 'łukasz langa': 'Łukasz Langa', 'walter dörwald': 'Walter Dörwald'}
(Представлен Jörn Heissler в bpo-35224.)
Теперь
object.__reduce__()
метод может вернуть кортеж длиной от двух до шести элементов. Раньше предельным было пять. Новый опциональный шестой элемент является вызываемым с(obj, state)
сигнатура. Это позволяет напрямую управлять поведением обновления состояния определенного объекта. Если не None, у этого подлежащего выкупу будет приоритет над__setstate__()
метод объекта. (Представлен Pierre Glaser и Olivier Grisel в bpo-35900.)
Новые модули¶
Новый модуль
importlib.metadata
обеспечивает (предварительную) поддержку для чтения метаданных из сторонних пакетов. Например, он может извлечь номер версии установленного пакета, список точек входа и многое другое:>>> # Note following example requires that the popular "requests" >>> # package has been installed. >>> >>> from importlib.metadata import version, requires, files >>> version('requests') '2.22.0' >>> list(requires('requests')) ['chardet (<3.1.0,>=3.0.2)'] >>> list(files('requests'))[:5] [PackagePath('requests-2.22.0.dist-info/INSTALLER'), PackagePath('requests-2.22.0.dist-info/LICENSE'), PackagePath('requests-2.22.0.dist-info/METADATA'), PackagePath('requests-2.22.0.dist-info/RECORD'), PackagePath('requests-2.22.0.dist-info/WHEEL')]
(Вклад Barry Warsaw и Jason R. Coombs в bpo-34632.)
Улучшение модулей¶
ast¶
Узлы AST теперь имеют атрибуты end_lineno
и end_col_offset
, которые дают точное
расположение конца узла. (Это только относится к узлам, у которых есть
lineno
и col_offset
атрибуты.)
Новая функция ast.get_source_segment()
возвращает источник код для определенного узла
AST.
(Представлен Ivan Levkivskyi в bpo-33416.)
Функция ast.parse()
имеет несколько новых флагов:
type_comments=True
приводит к возврату текста комментариев типа PEP 484 и PEP 526, связанных с определенными узлами AST;mode='func_type'
может быть используемый для разбора PEP 484 «сигнатура type comments» (возвращаемых для определения функции узлы AST);feature_version=(3, N)
позволяет указать более раннюю версию Python 3. Например,feature_version=(3, 4)
будет рассматриватьasync
иawait
как незарезервированные слова.
(Представлен Guido van Rossum в bpo-35766.)
asyncio¶
asyncio.run()
вышел из предварительного в стабильный API. Эта функция может быть
используемый, чтобы выполнить корутину и возвратить результат, автоматически
управляя событийный цикл. Например:
import asyncio
async def main():
await asyncio.sleep(0)
return 42
asyncio.run(main())
Это roughly эквивалентно:
import asyncio
async def main():
await asyncio.sleep(0)
return 42
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
loop.run_until_complete(main())
finally:
asyncio.set_event_loop(None)
loop.close()
Фактическая реализация значительно сложнее. Таким образом, asyncio.run()
должен
быть предпочтительным способом запуска программ asyncio.
(Внесено Yury Selivanov в bpo-32314.)
При запуске python -m asyncio
запускается асинхронный REPL. Это позволяет быстро
экспериментировать с код, который имеет верхний уровень await
.
Больше нет необходимости напрямую вызывать asyncio.run()
, что породило бы новую
событийный цикл при каждом вызове:
$ python -m asyncio
asyncio REPL 3.8.0
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> await asyncio.sleep(10, result='hello')
hello
(Представлен Yury Selivanov в bpo-37028.)
Исключение asyncio.CancelledError
теперь наследуется от
BaseException
, а не от Exception
, и больше не наследуется от
concurrent.futures.CancelledError
. (Внесено Юрием Селивановым в
bpo-32528.)
На Windows дефолт событийный цикл - теперь ProactorEventLoop
.
(Представлен Victor Stinner в bpo-34687.)
ProactorEventLoop
теперь также поддерживает UDP.
(Предоставлено Adam Meily и Andrew Svetlov в bpo-29883.)
Теперь ProactorEventLoop
может прерываться командой KeyboardInterrupt
(«CTRL+C»).
(Представлен Vladimir Matveev в bpo-23057.)
Добавлено asyncio.Task.get_coro()
для получения обернутой корутины в пределах asyncio.Task
.
(Вклад Alex Grönholm в bpo-36999.)
Теперь задачи Asyncio можно именовать либо путем передачи аргумента name
ключевой в asyncio.create_task()
или метод create_task()
событийный цикл, либо путем вызова метода set_name()
метод в
объекте задачи. Имя задачи видимо в продукции repr()
asyncio.Task
и
может также быть восстановлено, используя get_name()
метод.
(Представлен Alex Grönholm в bpo-34270.)
Добавлена поддержка Happy Eyeballs в asyncio.loop.create_connection()
. Для задания поведения были
добавлены два новых параметра: happy_eyeballs_delay и interleave. Алгоритм Happy
Eyeballs повышает быстродействие приложений, поддерживающих IPv4 и IPv6, путем
одновременной попытки подключения с использованием обоих.
(Представлен twisteroid ambassador в bpo-33530.)
builtins¶
Встроенное compile()
было улучшено, чтобы принять флаг ast.PyCF_ALLOW_TOP_LEVEL_AWAIT
.
Если этот новый флаг передан, compile()
будет разрешать конструкции верхнего уровня
await
, async for
и async with
, которые обычно считаются недопустимым
синтаксисом. Затем может быть возвращен асинхронный объект код,
помеченный флагом CO_COROUTINE
. (Предоставлено Matthias Bussonnier в bpo-34616)
collections¶
Теперь _asdict()
метод для collections.namedtuple()
возвращает dict
вместо collections.OrderedDict
. Это работает, потому что
регулярные документы гарантировали порядок с
Python 3.7. Если требуются дополнительные функции OrderedDict
, предлагаемое
исправление должно привести результат к требуемому типу: OrderedDict(nt._asdict())
.
(Представлен Raymond Hettinger в bpo-35864.)
cProfile¶
cProfile.Profile
класс может теперь быть используемый как менеджером контекст.
Выполните профилирование блока код:
import cProfile
with cProfile.Profile() as profiler:
# code to be profiled
...
(Предоставлено Scott Sanderson в bpo-29235.)
csv¶
Теперь csv.DictReader
возвращает сущности dict
вместо collections.OrderedDict
.
Инструмент теперь быстрее и использует меньше памяти, сохраняя при этом порядок
полей. (Представлен Michael Selik в bpo-34003.)
curses¶
Добавлена новая переменная, содержащая информацию о структурированной версии для
библиотеки ncurses: ncurses_version
.
(Представлен Serhiy Storchaka в bpo-31680.)
ctypes¶
В Windows CDLL
и подклассы теперь принимают параметр winmode, чтобы
указать флаги для базового вызова LoadLibraryEx
. Флаги по умолчанию устанавливаются
для загрузки только зависимостей DLL из надежных расположений, включая путь, по
которому хранится DLL (если для загрузки начальной DLL-библиотеки используемый
полный или частичный путь), и пути, добавляемые add_dll_directory()
.
(Предоставлено Steve Dower в bpo-36085.)
datetime¶
Добавлены новые альтернативные конструкторы datetime.date.fromisocalendar()
и datetime.datetime.fromisocalendar()
, которые
строят объекты date
и datetime
соответственно из года ISO, номера
недели и дня недели; это обратная величина для каждого класса isocalendar
метод. (Предоставлено Paul Ganssle в bpo-36004.)
functools¶
functools.lru_cache()
может теперь быть используемый как прямым декоратором, а не как
функция, возвратив декоратор. Так что оба они теперь поддерживаются:
@lru_cache
def f(x):
...
@lru_cache(maxsize=256)
def f(x):
...
(Представлен Raymond Hettinger в bpo-36772.)
Добавлен новый декоратор functools.cached_property()
для вычисляемых свойств, кэшированных для жизни
сущности.:
import functools
import statistics
class Dataset:
def __init__(self, sequence_of_numbers):
self.data = sequence_of_numbers
@functools.cached_property
def variance(self):
return statistics.variance(self.data)
(Представлен Carl Meyer в bpo-21145)
Добавлен новый декоратор functools.singledispatchmethod()
, который преобразует методы в
общие функции с помощью одиночной диспетчеризации:
from functools import singledispatchmethod
from contextlib import suppress
class TaskManager:
def __init__(self, tasks):
self.tasks = list(tasks)
@singledispatchmethod
def discard(self, value):
with suppress(ValueError):
self.tasks.remove(value)
@discard.register(list)
def _(self, tasks):
targets = set(tasks)
self.tasks = [x for x in self.tasks if x not in targets]
(Представлен Ethan Smith в bpo-32380)
gc¶
Теперь get_objects()
может получить необязательный параметр generation, указывающий
генерацию для получения объектов. (Представлен Pablo Galindo в bpo-36016.)
gettext¶
Добавлены pgettext()
и его варианты.
(Вклад Franz Glasner, Éric Araujo и Cheryl Sabella в bpo-2504.)
gzip¶
Добавлен параметр mtime в gzip.compress()
для воспроизводимого вывода.
(Внесён Guo Ci Teo в bpo-34898.)
Исключение BadGzipFile
теперь поднято вместо OSError
для определенных типов
инвалида или повреждённых gzip файлов.
(Вклад Filip Gruszczyński, Michele Orrù и Zackery Spyt в bpo-6584.)
IDLE и idlelib¶
Вывод по N линиям (по умолчанию 50) сжимается до кнопки. N можно изменить в разделе PyShell на странице общие диалогового окна настройки. Меньше, но, возможно, слишком длинных линий можно сжать, щелкнув правой кнопкой мыши на выходе. Сжатые выходные данные можно развернуть по месту, дважды нажав кнопку или в буфер обмена или в отдельном окне, щелкнув кнопку правой кнопкой мыши. (Внесен Tal Einat в bpo-1529353.)
Добавьте «Run Customized» в меню Run для запуска модуля с настроенными настройками. Все введенные аргументы командной строки добавляются в sys.argv. Они также повторно появляются в поле для следующего настраиваемого прогона. Можно также подавить обычный перезапуск основного модуля Shell. (Вклад Cheryl Sabella, Terry Jan Reedy и других в bpo-5680 и bpo-37627.)
Добавлены дополнительные номера строк для окон редактора IDLE. Окна открываются без номеров строк, если не указано иное на вкладке «Общие» диалогового окна конфигурации. Номера строк для существующего окна отображаются и скрываются в меню «Параметры». (Предоставлено Tal Einat и Saimadhav Heblikarв bpo-17535.)
Уроженцем OS кодировка является теперь используемый для преобразования между объектами Python строки и Tcl. Это позволяет IDLE работать с эмодзи и другими символами, отличными от BMP. Эти символы могут отображаться или копироваться и вставляться в буфер обмена или из него. Преобразование строки из Tcl в Python и обратно теперь никогда не завершается неудачно. (Многие люди работали над этим восемь лет, но проблема была окончательно решена Serhiy Storchaka в bpo-13153.)
Новое в 3.8.1:
Добавлена опция для отключения мигания курсора. (Внесен Закери Спицем в bpo-4603.)
Клавиша Escape теперь закрывает окна завершения простоя. (Вклад Джонни Наджеры в bpo-38944.)
Вышеприведенные изменения были перенесены обратно в версии технического обслуживания 3.7.
Добавлены ключевые слова в списоковое включение имени модуля. (Вклад Терри Дж. Риди в bpo-37765.)
inspect¶
Функция inspect.getdoc()
может теперь найти докстринги для __slots__
, если это,
атрибут - dict
, где значения - докстринги. Здесь представлены
варианты документации, аналогичные уже имеющимся у нас для property()
,
classmethod()
и staticmethod()
:
class AudioClip:
__slots__ = {'bit_rate': 'expressed in kilohertz to one decimal place',
'duration': 'in seconds, rounded up to an integer'}
def __init__(self, bit_rate, duration):
self.bit_rate = round(bit_rate / 1000.0, 1)
self.duration = ceil(duration)
(Представлен Raymond Hettinger в bpo-36326.)
io¶
В режиме разработки (-X
env
) и при отладочной сборке финализатор
io.IOBase
регистрирует исключение в случае сбоя close()
метод.
Исключение по умолчанию игнорируется без предупреждения при построении выпуска.
(Представлен Victor Stinner в bpo-18748.)
itertools¶
Функция itertools.accumulate()
добавила аргумент option initial ключевой для указания
начального значения:
>>> from itertools import accumulate
>>> list(accumulate([10, 5, 30, 15], initial=1000))
[1000, 1010, 1015, 1045, 1060]
(Внесена Lisa Roach в bpo-34659.)
json.tool¶
Добавьте опцию --json-lines
, чтобы разобрать каждую входную строку как отдельный
объект JSON. (Представлен Weipeng Hong в bpo-31553.)
logging¶
Добавлен ключевой аргумент force logging.basicConfig()
, когда установлено в
истинный, любые существующие обработчики были свойственны корневому логгеру
удалены и закрыты перед выполнением конфигурации, определенной другими
аргументами.
Это решает давнюю проблему. Как только вызов логгер или basicConfig() был вызван, последующие звонки в basicConfig() были молча проигнорированы. Это затрудняло обновление, экспериментирование или обучение различных опций конфигурации логирование с помощью интерактивного приглашения или блокнота Jupyter.
(Предложено Raymond Hettinger, реализовано Dong-hee Na и рассмотрено Vinay Sajip в bpo-33897.)
math¶
Добавлена новая функция math.dist()
для вычисления евклидового расстояния между
двумя точками. (Представлен Raymond Hettinger в bpo-33089.
Расширена функция math.hypot()
для обработки нескольких размеров. Ранее она
поддерживала только дело 2-D. (Представлен Raymond Hettinger в bpo-33089.
Добавлена новая функция math.prod()
, аналогичная функции sum()
, которая
возвращает произведение начального значения (по умолчанию: 1), умноженное на
интератор чисел:
>>> prior = 0.8
>>> likelihoods = [0.625, 0.84, 0.30]
>>> math.prod(likelihoods, start=prior)
0.126
(Представлен Pablo Galindo в bpo-35606.
Добавлены две новые комбинаторные функции math.perm()
и math.comb()
:
>>> math.perm(10, 3) # Permutations of 10 things taken 3 at a time
720
>>> math.comb(10, 3) # Combinations of 10 things taken 3 at a time
120
(Вклад Yash Aggarwal, Keller Fuchs, Serhiy Storchaka и Raymond Hettinger в bpo-37128, bpo-37178 и bpo-35431.)
Добавлена новая функция math.isqrt()
для вычисления точных целых квадратных
корней без преобразования в плавающую точку. Новая функция поддерживает
произвольно большие целые числа. Он быстрее floor(sqrt(n))
, но медленнее
math.sqrt()
:
>>> r = 650320427
>>> s = r ** 2
>>> isqrt(s - 1) # correct
650320426
>>> floor(sqrt(s - 1)) # incorrect
650320427
(Представлен Mark Dickinson в bpo-36887.)
Функция math.factorial()
больше не принимает аргументы, не похожие на int.
(Внесено Pablo Galindo в bpo-33083.)
mmap¶
Теперь mmap.mmap
класс имеет madvise()
метод для доступа к
системному вызову madvise()
. (Представлен Zackery Spytz в bpo-32941.)
multiprocessing¶
Добавлен новый модуль multiprocessing.shared_memory
.
(Представлен Davin Potts в bpo-35813.)
На macOS начинаются spawn, метод - теперь используемый по умолчанию. (Представлен Victor Stinner в bpo-33725.)
os¶
Добавлена новая функция add_dll_directory()
в Windows для предоставления дополнительных
путей поиска собственных зависимостей при импорте модулей расширений или
загрузке DLL с помощью ctypes
.
(Предоставлено Steve Dower в bpo-36085.)
Добавлена новая функция os.memfd_create()
для переноса memfd_create()
syscall.
(Представлен Zackery Spytz и Christian Heimes в bpo-26836.)
В Windows большая часть ручной логики для обработки точек повторной обработки
(включая симссылки и соединения каталогов) была делегирована операционной
системе. В частности, теперь os.stat()
будет пересекать все, что
поддерживается операционной системой, в то время как os.lstat()
будет открывать
только точки повторной обработки, которые идентифицируются как «суррогаты
имени», в то время как другие открываются как для os.stat()
. Во всех случаях у
stat_result.st_mode
только будет набор S_IFLNK
для символических ссылок и не других
видов точек переразбора. Чтобы определить другие виды точки переразбора,
проверьте новый stat_result.st_reparse_tag
атрибут.
Теперь в Windows os.readlink()
может читать узлы каталогов. Обратите внимание, что
islink()
возвратит False
для директивных соединений, и таким образом,
код, который проверяет islink
сначала, продолжит рассматривать
соединения как справочники, в то время как код, который обрабатывает
ошибки от os.readlink()
, может теперь рассматривать соединения как ссылки.
(Предоставлено Steve Dower в bpo-37834.)
os.path¶
os.path
функции, возвращающие логический результат, такие как exists()
,
lexists()
, isdir()
, isfile()
, islink()
и ismount()
, теперь возвращают False
вместо увеличения
ValueError
или его подклассы UnicodeEncodeError
и UnicodeDecodeError
для
путей, которые содержат символы или байты, непредставимые на уровне OS.
(Представлен Serhiy Storchaka в bpo-33721.)
expanduser()
в Windows теперь предпочитает переменную среды USERPROFILE
и не
использует HOME
, которая обычно не устанавливается для обычных учетных
записей пользователей. (Представлен Anthony Sottile в bpo-36264.)
isdir()
в Windows больше не возвращает True
для ссылки на
несуществующий каталог.
realpath()
в Windows теперь разрешает точки повторной обработки, включая ссылки
и соединения каталогов.
(Предоставлено Steve Dower в bpo-37834.)
pathlib¶
pathlib.Path
методы, возвращающие логический результат, такой как
exists()
, is_dir()
, is_file()
,
is_mount()
, is_symlink()
,
is_block_device()
, is_char_device()
,
is_fifo()
, is_socket()
, теперь возвращают False
вместо
увеличения ValueError
или его подкласс UnicodeEncodeError
для путей, которые
содержат символы, непредставимые на уровне OS.
(Представлен Serhiy Storchaka в bpo-33721.)
Добавлено pathlib.Path.link_to()
, создающее жесткую связь, указывающую на контур.
(Представлен Joannah Nanjekye в bpo-26978)
pickle¶
Расширения pickle
, подклассирующие C-оптимизированные Pickler
, теперь
могут переопределять логику pickling функций и классы, определяя
специальные reducer_override()
метод.
(Вклад Pierre Glaser и Olivier Grisel в bpo-35900.)
plistlib¶
Добавленный новый plistlib.UID
и включил поддержку чтения и написания набора из
двух предметов NSKeyedArchiver-кодированный plists.
(Представлен Jon Janzen в bpo-26707.)
pprint¶
Модуль pprint
добавил параметр sort_dicts к нескольким функциям. По
умолчанию эти функции продолжают сортировать словари перед визуализацией или
печатью. Однако, если sort_dicts установлен в ложный, словари сохраняют порядок,
что ключи были вставлены. Это может быть полезно для сравнения с входными
данными JSON во время отладки.
Кроме того, есть удобство новая функция, pprint.pp()
, который похож на
pprint.pprint()
, но с sort_dicts, не выполняющим своих обязательств к False
:
>>> from pprint import pprint, pp
>>> d = dict(source='input.txt', operation='filter', destination='output.txt')
>>> pp(d, width=40) # Original order
{'source': 'input.txt',
'operation': 'filter',
'destination': 'output.txt'}
>>> pprint(d, width=40) # Keys sorted alphabetically
{'destination': 'output.txt',
'operation': 'filter',
'source': 'input.txt'}
(Вклад Rémi Lapeyre в bpo-30670.)
py_compile¶
Теперь py_compile.compile()
поддерживает бесшумный режим.
(Представлен Joannah Nanjekye в bpo-22640.)
shlex¶
Новая функция shlex.join()
действует как инверсия shlex.split()
.
(Представлен Bo Bayles в bpo-32102.)
shutil¶
Теперь shutil.copytree()
принимает новый ключевой аргумент dirs_exist_ok
.
(Предоставлено Josh Bronson в bpo-20849.)
shutil.make_archive()
теперь не выполняют своих обязательств к современному миру
(POSIX.1-2001) формат, чтобы новые архивы улучшили мобильность и соответствие
стандартов, унаследованное от соответствующего изменения до модуля tarfile
.
(Автор: C.A.M. Gerlach в bpo-30661.)
shutil.rmtree()
в Windows теперь удаляет соединения каталогов без рекурсивного
удаления их содержимого. (Предоставлено Steve Dower в bpo-37834.)
socket¶
Добавлены функции удобства create_server()
и has_dualstack_ipv6()
для автоматизации необходимых задач, обычно задействованных при создании серверного сокета,
включая прием как IPv4, так и IPv6 подключений на одном и том же сокет.
(Автор - Giampaolo Rodolà в bpo-17561.)
Функции socket.if_nameindex()
, socket.if_nametoindex()
и socket.if_indextoname()
реализованы в Windows.
(Представлен Zackery Spytz в bpo-37007.)
ssl¶
Добавленный post_handshake_auth
, чтобы включить и verify_client_post_handshake()
, чтобы начать
идентификацию TLS 1.3 пострукопожатия.
(Представлен Christian Heimes в bpo-34670.)
statistics¶
Добавленный statistics.fmean()
как более быстрый вариант с плавающей запятой
statistics.mean()
.
(Представлен Raymond Hettinger и Steven D’Aprano в bpo-35904.)
Добавлено statistics.geometric_mean()
(внесено Raymond Hettinger в bpo-27181.)
Добавленный statistics.multimode()
, который возвращает список из наиболее распространенных
ценностей. (Представлен Raymond Hettinger в bpo-35892.)
Добавлено statistics.quantiles()
, которое делит данные или распределение в к настраиваемым
интервалам (например, квартили, децили или процентили).
(Представлен Raymond Hettinger в bpo-36546.)
Добавленный statistics.NormalDist
, инструмент для создания и управления нормальными
распределениями случайной переменной. (Представлен Raymond Hettinger в
bpo-36018.)
>>> temperature_feb = NormalDist.from_samples([4, 12, -3, 2, 7, 14])
>>> temperature_feb.mean
6.0
>>> temperature_feb.stdev
6.356099432828281
>>> temperature_feb.cdf(3) # Chance of being under 3 degrees
0.3184678262814532
>>> # Relative chance of being 7 degrees versus 10 degrees
>>> temperature_feb.pdf(7) / temperature_feb.pdf(10)
1.2039930378537762
>>> el_niño = NormalDist(4, 2.5)
>>> temperature_feb += el_niño # Add in a climate effect
>>> temperature_feb
NormalDist(mu=10.0, sigma=6.830080526611674)
>>> temperature_feb * (9/5) + 32 # Convert to Fahrenheit
NormalDist(mu=50.0, sigma=12.294144947901014)
>>> temperature_feb.samples(3) # Generate random samples
[7.672102882379219, 12.000027119750287, 4.647488369766392]
sys¶
Добавьте новую функцию sys.unraisablehook()
, которая может быть переопределена для
управления обработкой «неразрешимых исключений». Это называют, когда исключение
произошло, но нет никакого пути к Python, чтобы обращаться с ним. Например,
когда деструктор вызывает исключение или во время сборки мусора (gc.collect()
).
(Представлен Victor Stinner в bpo-36829.)
tarfile¶
Модуль tarfile
теперь по умолчанию использует современный формат pax
(POSIX.1-2001) для новых архивов вместо предыдущего формата GNU. Это повышает
переносимость между платформами с помощью согласованного кодировка (UTF-8) в
стандартизированном и расширяемом формате и предлагает ряд других преимуществ.
(Автор: C.A.M. Gerlach в bpo-36268.)
threading¶
Добавьте новую функцию threading.excepthook()
, которая обрабатывает необученное исключение
threading.Thread.run()
. Она может быть переопределена для управления обработкой
необнаруженных исключений threading.Thread.run()
. (Представлен Victor Stinner в
bpo-1230540.)
Добавьте новую функцию threading.get_native_id()
и функцию native_id
атрибут к threading.Thread
класс. Они возвращают собственный интегральный
идентификатор потока текущего поток, назначенного ядром. Эта функция доступна только на
определенных платформах, см. раздел get_native_id
для получения дополнительной информации. (Представлен Jake Tesler в bpo-36084.)
tokenize¶
Модуль tokenize
теперь неявно выдает токен NEWLINE
, когда ему
предоставляется вход, который не имеет конечной новой строки. Это поведение
теперь совпадает с тем, что делает внутренний токенизатор C.
(Представлен Ammar Askar в bpo-33899.)
tkinter¶
Добавлены методы selection_from()
,
selection_present()
,
selection_range()
и selection_to()
в
tkinter.Spinbox
класс. (Внесена Juliette Monsel в bpo-34829.)
Добавлено метод moveto()
в tkinter.Canvas
класс.
(Вклад Juliette Monsel в bpo-23831.)
В tkinter.PhotoImage
класс теперь есть transparency_get()
и transparency_set()
методы.
(Представлен Zackery Spytz в bpo-25451.)
time¶
Добавленные новые часы CLOCK_UPTIME_RAW
для macOS 10.12.
(Представлен Joannah Nanjekye в bpo-35702.)
typing¶
Модуль typing
включает в себя несколько новых функций:
Тип словаря с типами ключей. См. PEP 589 и
typing.TypedDict
. TypedDict использует только ключи строка. По умолчанию каждый ключ должен присутствовать. Укажите «total = False», чтобы ключи были необязательными:class Location(TypedDict, total=False): lat_long: tuple grid_square: str xy_coordinate: tuple
Буквальные типы. См. PEP 586 и
typing.Literal
. Типы литералов указывают, что параметр или возвращаемое значение ограничено одним или несколькими конкретными значениями литерал:def get_status(port: int) -> Literal['connected', 'disconnected']: ...
«Окончательные» переменные, функции, методы и классы. См. PEP 591,
typing.Final
иtyping.final()
. Окончательный квалификатор предписывает средству проверки статического типа ограничить подклассы, переопределения или переназначения:pi: Final[float] = 3.1415926536
Определения протокола. См. PEP 544,
typing.Protocol
иtyping.runtime_checkable()
. Простые ABCs, какtyping.SupportsInt
теперьProtocol
подклассы.Новый протокол класс
typing.SupportsIndex
.Новые функции
typing.get_origin()
иtyping.get_args()
.
unicodedata¶
Модуль unicodedata
обновлен для использования версии Unicode 12.1.0.
Новая функция is_normalized()
может быть используемый для проверки того, что
строка находится в определенной нормальной форме, часто гораздо быстрее,
чем путем фактической нормализации строка.
(Вклад Max Belanger, David Euresti и Greg Price в bpo-32285 и bpo-37966).
unittest¶
Добавлено AsyncMock
для поддержки асинхронной версии
Mock
. Также добавлены соответствующие новые функции утверждения
для тестирования. (Внесена Lisa Roach в bpo-26467).
Добавлены addModuleCleanup()
и addClassCleanup()
,
чтобы unittest поддерживать очистки для setUpModule()
и
setUpClass()
.
(Внесена Lisa Roach в bpo-24412.)
Несколько функций mock assert теперь также печатают список фактических вызовов при сбое. (Представлен Petter Strandmark в bpo-35047.)
Модуль unittest
получил поддержку coroutines, которые должны быть используемый
в качестве тестовых случаев с unittest.IsolatedAsyncioTestCase
.
(Представлен Andrew Svetlov в bpo-32972.)
Пример:
import unittest
class TestRequest(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
self.connection = await AsyncConnection()
async def test_get(self):
response = await self.connection.get("https://example.com")
self.assertEqual(response.status_code, 200)
async def asyncTearDown(self):
await self.connection.close()
if __name__ == "__main__":
unittest.main()
venv¶
venv
теперь включает скрипт Activate.ps1
на всех платформах для активации
виртуальных сред в PowerShell Core 6.1. (Представлен Brett Cannon в bpo-32718.)
weakref¶
Прокси-объекты, возвращаемые weakref.proxy()
, теперь поддерживают операторы умножения
матрицы @
и @=
в дополнение к другим числовым операторам.
(Представлен Mark Dickinson в bpo-36669.)
xml¶
Как смягчение по отношению к DTD и извлечению внешнего объекта, модули
xml.dom.minidom
и xml.sax
больше не обрабатывают внешние объекты по умолчанию.
(Представлен Christian Heimes в bpo-17239.)
.find*()
методы в модуле xml.etree.ElementTree
поддерживают подстановочный символ
поиска, например {*}tag
, который игнорирует пространство имен и {namespace}*
который возвращает все теги в данном пространстве имен.
(Представлен Stefan Behnel в bpo-28238.)
Модуль xml.etree.ElementTree
предоставляет новую функцию –xml.etree.ElementTree.canonicalize()
, реализующую C14N
2.0. (Внесён Stefan Behnel в bpo-13611.)
Целевой объект xml.etree.ElementTree.XMLParser
может принимать события объявления
пространства имен через новые колбэк методы start_ns()
и end_ns()
. Кроме того, цель
xml.etree.ElementTree.TreeBuilder
может быть настроена, чтобы обработать события о комментариях и
инструкциях по обработке включать их в произведенное дерево. (Представлен
Stefan Behnel в bpo-36676 и bpo-36673.)
xmlrpc¶
Теперь xmlrpc.client.ServerProxy
поддерживает дополнительный аргумент headers ключевой
для последовательности заголовков HTTP, отправляемых с каждым запросом. Помимо
прочего, это позволяет обновить базовую аутентификацию по умолчанию до более
быстрой аутентификации сеанса. (Представлен Cédric Krier в документе bpo-35153.)
Оптимизация¶
Модуль
subprocess
теперь может использовать функциюos.posix_spawn()
в некоторых случаях для повышения производительности. В настоящее время он используемый только на macOS и Linux (с использованием glibc 2.24 или новее), если все эти условия выполнены:- close_fds равен false;
- preexec_fn, pass_fds, cwd и start_new_session параметры не установлены;
- executable путь содержащий каталог.
(Вклад Joannah Nanjekye и Victor Stinner в bpo-35537.)
shutil.copyfile()
,shutil.copy()
,shutil.copy2()
,shutil.copytree()
иshutil.move()
используют зависящие от платформы «быстрые копии» syscalls в Linux и macOS для более эффективного копирования файла. «быстрое копирование» означает, что операция копирования происходит внутри ядра, избегая использования буферов пользовательского пространства в Python, как в «outfd.write(infd.read())
.» на использовании Windowsshutil.copyfile()
больший размер буфера по умолчанию (1 MiB вместо 16 KiB) и основанный наmemoryview()
вариантshutil.copyfileobj()
является используемый. Ускорение копирования файла 512 MiB в том же разделе составляет около 26% в Linux, 50% в macOS и 40% в Windows. Кроме того, используется гораздо меньше циклов CPU. См. раздел Зависящие от платформы эффективные операции копирования. (Автор - Giampaolo Rodolà в документе bpo-33671.)shutil.copytree()
использует функциюos.scandir()
, а все функции копирования в зависимости от нее используют кэшированные значенияos.stat()
. Ускорение копирования каталога с 8000 файлами составляет около 9% для Linux, 20% для Windows и 30% для общего ресурса Windows SMB. Также количествоos.stat()
syscalls сокращено на 38%, делающихshutil.copytree()
особенно быстрее в сетевых файловых системах. (Представлен Giampaolo Rodolà в bpo-33695.)Протоколом по умолчанию в модуле
pickle
теперь является протокол 4, впервые представленный в Python 3.4. Он обеспечивает более высокую производительность и меньший размер по сравнению с протоколом 3, доступным с Python 3.0.Удален один элемент
Py_ssize_t
изPyGC_Head
. Размер всех отслеживаемых объектов GC (например, кортежа, списка, dict) уменьшается на 4 или 8 байт. (Внесена Inada Naoki в bpo-33597.)Теперь
uuid.UUID
использует__slots__
, чтобы уменьшить объем памяти. (Вклад Wouter Bolsterlee и Tal Einat в bpo-30977)Повышение производительности
operator.itemgetter()
на 33%. Оптимизированная обработка аргументов и добавление быстрого пути для общего случая одного неотрицательного целочисленного индекса в кортеж (что является типичным случаем использования в стандартной библиотеке). (Представлен Raymond Hettinger в bpo-35664.)Ускоренный поиск полей в
collections.namedtuple()
. Они теперь больше чем в два раза быстрее, делая их самой быстрой формой переменного поиска сущность в Python. (Вклад Raymond Hettinger, Pablo Galindo и Joe Jevnik, Serhiy Storchaka в bpo-32492.)Конструктор
list
не перераспределяет внутренний буфер элементов, если входной итератор имеет известную длину (на входе реализован__len__
). Это делает созданный список в среднем на 12% меньше. (Вклад Raymond Hettinger и Pablo Galindo в bpo-33234.)Удвоение скорости записи переменной класс. Когда non-dunder атрибут был обновлен, было ненужное требование обновить места. (Вклад Stefan Behnel, Pablo Galindo Salgado, Raymond Hettinger, Neil Schemenauer и Serhiy Storchaka в bpo-36012.)
Уменьшение накладных расходов на преобразование аргументов, передаваемых во многие функции построения и методы. Это ускорило вызов некоторых простых функций построения и методы до 20 - 50%. (Представлен Serhiy Storchaka в bpo-23867, bpo-35582 и bpo-36127.)
В инструкции
LOAD_GLOBAL
теперь используется новый механизм «per opcode cache». Сейчас это примерно на 40% быстрее. (Представлен Yury Selivanov и инадой наоки в bpo-26219.)
Изменения C API и сборки¶
Дефолт
sys.abiflags
стал пустой последовательностью: флагm
для pymalloc стал бесполезным (строит с, и без pymalloc ABI совместимый), и удаленный - также. (Представлен Victor Stinner в bpo-36707.)Пример изменений:
- Только программа
python3.8
установлена, программыpython3.8m
не стало. - Установлен только скрипт
python3.8-config
,python3.8m-config
скрипт исчез. - Флаг
m
был удален из суффикса имен файлов динамической библиотеки: модулей расширений в стандартной библиотеке, а также модулей, созданных и установленных сторонними пакетами, например, загруженных из PyPI. В Linux, например, суффикс Python 3.7.cpython-37m-x86_64-linux-gnu.so
стал.cpython-38-x86_64-linux-gnu.so
в Python 3.8.
- Только программа
Заголовочные файлы были реорганизованы для лучшего разделения различных типов API:
Include/*.h
должен быть портативным public стабильным C API.Include/cpython/*.h
должен быть нестабильным C API, специфичным для CPython; public API, с некоторым частным API, префиксом_Py
или_PY
.Include/internal/*.h
является частным внутренним API C, очень специфичным для CPython. Этот API не имеет гарантии обратной совместимости и не должен быть используемый вне CPython. Он доступен только для очень специфических потребностей, таких как отладчики и профили, которые имеют доступ к внутренним CPython без вызова функций. Этот API теперь установленmake install
.
(Представлен Victor Stinner в bpo-35134 и bpo-35081, работа инициирована Eric Snow в Python 3.7.)
Некоторые макросы были преобразованы в статические встроенные функции: типы параметров и возвращаемый тип хорошо определены, они не имеют проблем, специфичных для макросов, переменные имеют локальная области видимости. Примеры:
Py_INCREF()
,Py_DECREF()
Py_XINCREF()
,Py_XDECREF()
PyObject_INIT()
,PyObject_INIT_VAR()
- Приватные функции:
_PyObject_GC_TRACK()
,_PyObject_GC_UNTRACK()
,_Py_Dealloc()
(Представлен Victor Stinner в bpo-35059.)
Функции
PyByteArray_Init()
иPyByteArray_Fini()
удалены. Они ничего не сделали, поскольку Python 2.7.4 и Python 3.2.0, были исключены из ограниченного API (стабильный ABI) и не были задокументированы. (Представлен Victor Stinner в bpo-35713.)Результат
PyExceptionClass_Name()
теперь типconst char *
, а неchar *
. (Представлен Serhiy Storchaka в bpo-33818.)Двойственность
Modules/Setup.dist
иModules/Setup
устранена. Ранее при обновлении исходного дерева CPython приходилось вручную копироватьModules/Setup.dist
(внутри исходного дерева) вModules/Setup
(внутри дерева построения), чтобы отразить любые изменения в восходящем направлении. Это имело небольшое преимущество для пакетов в ущерб частому раздражению разработчиков после разработки CPython, так как забывание скопировать файл могло привести к сбоям сборки.Теперь построить система всегда читает от
Modules/Setup
в исходном дереве. Людям, которые хотят настроить этот файл, рекомендуется сохранять свои изменения в git- вилке CPython или в виде файлов исправлений, как это было бы сделано для любого другого изменения исходного дерева.(Предоставлено Antoine Pitrou в bpo-32430.)
Функции, которые преобразуют Python число в C целое подобное
PyLong_AsLong()
и аргумент парсинг функции подобнойPyArg_ParseTuple()
с целым преобразование единиц формата, как'i'
теперь будет использовать__index__()
специальное метод вместо__int__()
, если доступно. Запрещение, предупреждающее, будет испускаться для объектов с__int__()
метод, но без__index__()
метод (какDecimal
иFraction
).:c:func:PyNumber_Check теперь возвратит1
для объектов, осуществляющих__index__()
.:c:func:PyNumber_LongPyNumber_Float()
иPyFloat_AsDouble()
также теперь использует__index__()
метод при наличии. (Представлен Serhiy Storchaka в bpo-36048 и bpo-20092.)Объекты типа, выделенные кучой, теперь увеличат число ссылок в
PyObject_Init()
(и их параллельный макросPyObject_INIT
), а не вPyType_GenericAlloc()
. Типы, которые изменяют распределение сущность или освобождение, возможно, должны быть приспособлены. (Представлен Eddie Elizondo в bpo-35810.)Новая функция
PyCode_NewWithPosOnlyArgs()
позволяет создавать код объекты подобныеPyCode_New()
, но с дополнительным параметром posonlyargcount для указания количества аргументов только позиции. (Представлен Pablo Galindo в bpo-37221.)Py_SetPath()
теперь устанавливаетsys.executable
в программу весь путь (Py_GetProgramFullPath()
), а не к названию программы (Py_GetProgramName()
). (Представлен Victor Stinner в bpo-38234.)
Запрещённые¶
Команда distutils
bdist_wininst
теперь осуждается, используйтеbdist_wheel
(пакеты wheel) вместо этого. (Представлен Victor Stinner в bpo-37481.)Устаревшие методы
getchildren()
иgetiterator()
в модулеElementTree
теперь испускаютDeprecationWarning
вместоPendingDeprecationWarning
. Они будут удалены в Python 3.9. (Представлен Serhiy Storchaka в bpo-29209.)Прохождение объекта, который не является сущность
concurrent.futures.ThreadPoolExecutor
кloop.set_default_executor()
, осуждается и будет запрещено в Python 3.9. (Представлен Elvis Pranskevichus в bpo-34075.)__getitem__()
методыxml.dom.pulldom.DOMEventStream
,wsgiref.util.FileWrapper
иfileinput.FileInput
были запрещён.Реализации этих методы игнорируют свой параметр index и возвращают следующий элемент. (Представлен Berker Peksag в bpo-9372.)
В
typing.NamedTuple
класс устарел_field_types
атрибут в пользу__annotations__
атрибут, который имеет ту же информацию. (Представлен Raymond Hettinger в bpo-36320.)ast
классыNum
,Str
,Bytes
,NameConstant
иEllipsis
считаются устаревшими и будут удалены в будущих версиях Python.Constant
должен быть используемый вместо этого. (Представлен Serhiy Storchaka в bpo-32892.)ast.NodeVisitor
методыvisit_Num()
,visit_Str()
,visit_Bytes()
,visit_NameConstant()
иvisit_Ellipsis()
устарели сейчас и не будут вызываться в будущих версиях Python. Добавьтеvisit_Constant()
метод для обработки всех постоянных узлов. (Представлен Serhiy Storchaka в bpo-36917.)Файл
asyncio.coroutine()
декоратор устарел и будет удален в версии 3.10. Вместо@asyncio.coroutine
используйтеasync def
. (Представлен Andrew Svetlov в bpo-36921.)В
asyncio
явное прохождение аргумента loop было запещено и будет удалено в версии 3.10 для следующего:asyncio.sleep()
,asyncio.gather()
,asyncio.shield()
,asyncio.wait_for()
,asyncio.wait()
,asyncio.as_completed()
,asyncio.Task
,asyncio.Lock
,asyncio.Event
,asyncio.Condition
,asyncio.Semaphore
,asyncio.BoundedSemaphore
,asyncio.Queue
,asyncio.create_subprocess_exec()
иasyncio.create_subprocess_shell()
.Явная передача объектов корутины в
asyncio.wait()
устарела и будет удалена в версии 3.11. (Представлено Yury Selivanov в bpo-34790.)Следующие функции и методы осуждаются в модуле
gettext
:lgettext()
,ldgettext()
,lngettext()
иldngettext()
. Они возвращают байты кодированный, и возможно, что вы получите неожиданные Unicode-связанные исключения, если будут проблемы кодировка с переведенным строки. Гораздо лучше использовать альтернативы, возвращающие юникод строки в Python 3. Эти функции были нарушены уже давно.bind_textdomain_codeset()
функции, методыoutput_charset()
иset_output_charset()
и параметр codeset функций,translation()
иinstall()
также осуждаются, так как они - только используемый для функцийl*gettext()
. (Представлен Serhiy Storchaka в bpo-33710.)Значение
isAlive()
методthreading.Thread
устарело. (Внесён Dong-hee Na в bpo-35283.)Много встроенных и дополнительных функций, которые берут целочисленные аргументы, теперь испустят предупреждение запрещёния для
Decimal
s,Fraction
s и любых других объектов, которые могут быть преобразованы в целые числа только с потерей (например, которые имеют__int__()
метод, но не имеют метода__index__()
). В будущей версии это будут ошибки. (Представлен Serhiy Storchaka в bpo-36048.)Отменена передача следующих аргументов в качестве аргументов ключевой:
- func в
functools.partialmethod()
,weakref.finalize()
,profile.Profile.runcall()
,cProfile.Profile.runcall()
,bdb.Bdb.runcall()
,trace.Trace.runfunc()
иcurses.wrapper()
. - function в
unittest.TestCase.addCleanup()
. - fn в
submit()
метод изconcurrent.futures.ThreadPoolExecutor
иconcurrent.futures.ProcessPoolExecutor
. - callback в
contextlib.ExitStack.callback()
,contextlib.AsyncExitStack.callback()
иcontextlib.AsyncExitStack.push_async_callback()
. - c и typeid в
create()
метод изmultiprocessing.managers.Server
иmultiprocessing.managers.SharedMemoryServer
. - obj в
weakref.finalize()
.
В будущих релизах Python они будут только позиционными. (Представлен Serhiy Storchaka в bpo-36492.)
- func в
Удаление API и функций¶
Следующие функции и API были удалены из Python 3,8:
- Начиная с Python 3,3 импорт ABC из
collections
устарел, а импорт должен выполняться изcollections.abc
. Возможность импорта из коллекций была отмечена для удаления в 3.8, но была отложена до 3.9. (См. bpo-36952.) - Модуль
macpath
, устаревший в Python 3.7, удален. (Представлен Victor Stinner в bpo-35471.) - Функция
platform.popen()
была удалена после того, как устарела с Python 3.3: используйтеos.popen()
. (Представлен Victor Stinner в bpo-35345.) - Функция
time.clock()
была удалена после того, как устарела с Python 3.3: использоватьtime.perf_counter()
илиtime.process_time()
вместо этого, в зависимости от ваших требований, чтобы иметь четко определенное поведение. (Представлен Matthias Bussonnier в bpo-36895.) - Сценарий
pyvenv
был удален в пользуpython3.8 -m venv
, чтобы помочь устранить беспорядок относительно того, к какому Python интерпретатор сценарийpyvenv
связан. (Представлен Brett Cannon в bpo-25427.) parse_qs
,parse_qsl
иescape
извлекаются из модуляcgi
. Они устарели в Python 3.2 или старше. Вместо этого их следует импортировать из модулейurllib.parse
иhtml
.- Функция
filemode
удаляется из модуляtarfile
. Он не документирован и устарел с Python 3.3. - Конструктор
XMLParser
больше не принимает аргумент html. Он никогда не имел эффекта и был запрещён в Python 3.4. Все остальные параметры теперь keyword-only. (Представлен Serhiy Storchaka в bpo-29209.) - Удалён
doctype()
методXMLParser
. (Представлен Serhiy Storchaka в bpo-29209.) - «unicode_internal» кодировка удаляется. (Внесена Inada Naoki в bpo-36297.)
Cache
и объектыStatement
модуляsqlite3
не выставлены пользователю. (Предоставлено Aviv Palivoda в bpo-30262.)- Ключевой аргумент
bufsize
fileinput.input()
иfileinput.FileInput()
, который был пропущен и устарел с Python 3.6, был удален. bpo-36952 (Автор - Matthias Bussonnier.) - Функции
sys.set_coroutine_wrapper()
иsys.get_coroutine_wrapper()
, устаревшие в Python 3.7, были исключены; bpo-36933 (Автор - Matthias Bussonnier.)
Портирование на Python 3.8¶
В этом разделе перечислены ранее описанные изменения и другие ошибки, которые могут потребовать изменения вашего код.
Изменения в поведении Python¶
- Выражения yield (как
yield
, так иyield from
) теперь не разрешены в представлениях и выражениях генератор (помимо итерабельного выражения в крайнем левом предложенииfor
). (Предоставлено Serhiy Storchaka в bpo-10544.) - Компилятор теперь создает
SyntaxWarning
, когда проверки удостоверений (is
иis not
) используемый с определенными типами литералов (например, строки, числа). Они могут часто работать случайно в CPython, но не гарантируются языковой spec. Предупреждение советует пользователям использовать тесты на равенство (==
и!=
) вместо этого. (Представлен Serhiy Storchaka в bpo-34850.) - CPython интерпретатор может глотать исключения при некоторых обстоятельствах. В Python 3.8 это происходит в меньшем количестве случаев. В частности, исключения, возникшие при получении атрибут из словаря типов, больше не игнорируются. (Представлен Serhiy Storchaka в bpo-35459.)
- Удаленные внедрения
__str__
от встроенных типовbool
,int
,float
,complex
и немного классы из стандартной библиотеки. Теперь они наследуют__str__()
отobject
. В результате определение__repr__()
метод в подкласс этих классы повлияет на их представление строка. (Представлен Serhiy Storchaka в bpo-36793.) - В AIX
sys.platform
больше не содержит основной версии. Это всегда'aix'
, вместо'aix3'
..'aix7'
. Так как старые версии Python включают номер версии, поэтому рекомендуется всегда использоватьsys.platform.startswith('aix')
. (Внесен M. Felt в bpo-36588.) PyEval_AcquireLock()
иPyEval_AcquireThread()
теперь завершают текущий поток, если вызывается, пока интерпретатор завершает работу, делая их согласованными сPyEval_RestoreThread()
,:c:func:Py_END_ALLOW_THREADS иPyGILState_Ensure()
. Если такое поведение не требуется, защитите вызов от вызова проверки_Py_IsFinalizing()
илиsys.is_finalizing()
. (Представлен Joannah Nanjekye в bpo-36475.)
Изменения в API Python¶
- Функция
os.getcwdb()
теперь использует UTF-8 кодировка на Windows, а не кодировку ANSI : см. PEP 529 для объяснения. Функция больше не устарела в Windows. (Представлен Victor Stinner в bpo-37412.) subprocess.Popen
может теперь использоватьos.posix_spawn()
в некоторых случаях для лучшего исполнения. В подсистеме Windows для Linux и эмуляции пользователя QEMU конструкторPopen
, использующийos.posix_spawn()
, больше не вызывает исключение при таких ошибках, как «отсутствующая программа». Вместо этого дочерний процесс терпит неудачу с отличным от нуляreturncode
. (Вклад Joannah Nanjekye и Victor Stinner в bpo-35537.)- Аргумент preexec_fn *
subprocess.Popen
больше не совместим с субинтерпретерами. Использование параметра в субинтерпреторе теперь вызываетRuntimeError
. (Представлен Eric Snow в bpo-34651, модифицирован Christian Heimes в bpo-37951.) imap.IMAP4.logout()
метод больше не игнорирует произвольные исключения. (Представлен Victor Stinner в bpo-36348.)- Функция
platform.popen()
была удалена после того, как устарела с Python 3.3: используйтеos.popen()
. (Представлен Victor Stinner в bpo-35345.) - Функция
statistics.mode()
больше не вызывает исключения при предоставлении мультимодальных данных. Вместо этого возвращается первый режим, встречающийся во входных данных. (Представлен Raymond Hettinger в bpo-35892.) selection()
методtkinter.ttk.Treeview
класс больше не принимают аргументы. Использование его с аргументами для изменения выделенной области устарело в Python 3.6. Используйте специализированные методы, какselection_set()
, для изменения выбора. (Представлен Serhiy Storchaka в bpo-31508.)writexml()
,toxml()
иtoprettyxml()
методыxml.dom.minidom
иwrite()
методxml.etree
, теперь сохраняют порядок атрибута, определенный пользователем. (Вклад Diego Rojas и Raymond Hettinger в bpo-34160.)- База данных
dbm.dumb
, открытая с флагами'r'
, теперь доступна только для чтения.dbm.dumb.open()
с флагами'r'
и'w'
больше не создает базу данных, если она не существует. (Представлен Serhiy Storchaka в bpo-32749.) doctype()
метод, определенный в подклассXMLParser
, больше не будет вызываться и будет испускатьRuntimeWarning
вместоDeprecationWarning
. Определитеdoctype()
метод на целевом объекте для обработки объявления типа документа XML. (Представлен Serhiy Storchaka в bpo-29209.)- Теперь
RuntimeError
возникает, когда пользовательский метакласс не предоставляет запись__classcell__
в пространстве имен, переданномtype.__new__
. В Python 3.6-3.7 испускалсяDeprecationWarning
. (Представлен Serhiy Storchaka в bpo-23722.) cProfile.Profile
класс может теперь быть используемый как менеджером контекст. (Представлен Scott Sanderson в bpo-29235.)shutil.copyfile()
,shutil.copy()
,shutil.copy2()
,shutil.copytree()
иshutil.move()
используют специфичные для платформы «быстрые копии» syscalls (см. раздел Зависящие от платформы эффективные операции копирования).shutil.copyfile()
по умолчанию размер буфера в Windows был изменен с 16 KiB на 1 MiB.- Структура
PyGC_Head
полностью изменилась. Все код, которые коснулись элемента структуры, должны быть переписаны. (См. bpo-33597.) - Структура
PyInterpreterState
была перемещена во «внутренние» заголовочные файлы (конкретно Include/internal/pycore_pystate.h). НепрозрачныйPyInterpreterState
все еще доступен как часть public API (и стабильный ABI). Документы указывают, что ни одно из полей структуры не является открытым, поэтому мы надеемся, что никто не использовал их. Однако, если вы полагаетесь на одно или несколько из этих частных полей и у вас нет альтернативы, пожалуйста, откройте проблему BPO. Мы будем работать над помощью вам приспособиться (возможно включая добавление accessor функции к public API). (См. bpo-35886.) - Теперь
mmap.flush()
метод возвращаетNone
на успех и вызывает исключение при ошибке на всех платформах. Ранее его поведение было платформенно- зависимым: при успехе возвращалось ненулевое значение; при ошибке в Windows возвращен нуль. При успехе возвращено нулевое значение; возникло исключение при ошибке в Unix. (Представлен Berker Peksag в bpo-2122.) - Модули
xml.dom.minidom
иxml.sax
больше не обрабатывают внешние объекты по умолчанию. (Представлен Christian Heimes в bpo-17239.) - Удаление ключа из доступной только для чтения базы данных
dbm
(dbm.dumb
,dbm.gnu
илиdbm.ndbm
) вызываетerror
(dbm.dumb.error
,dbm.gnu.error
илиdbm.ndbm.error
) вместоKeyError
. (Представлен Xiang Zhang в bpo-33106.) - Упрощенный AST для литералов. Все константы будут представлены как
ast.Constant
сущности. Создание экземпляра старых классыNum
,Str
,Bytes
,NameConstant
иEllipsis
вернет сущностьConstant
. (Представлен Serhiy Storchaka в bpo-32892.) expanduser()
в Windows теперь предпочитает переменную средыUSERPROFILE
и не используетHOME
, которая обычно не устанавливается для обычных учетных записей пользователей. (Представлен Anthony Sottile в bpo-36264.)- Исключение
asyncio.CancelledError
теперь наследуется отBaseException
, а не отException
, и больше не наследуется отconcurrent.futures.CancelledError
. (Внесено Юрием Селивановым в bpo-32528.) - Функция
asyncio.wait_for()
теперь правильно ждет отмены, используя сущностьasyncio.Task
. Ранее по достижении timeout он отменялся и немедленно возвращался. (Представлен Elvis Pranskevichus в bpo-32751.) - Функция
asyncio.BaseTransport.get_extra_info()
теперь возвращает безопасный для использования объект сокет, когда «сокет» передается параметру name. (Представлен Yury Selivanov в н640382364.) asyncio.BufferedProtocol
вышел на стабильный API.
- Зависимости DLL для модулей расширений и DLL, загруженных с помощью
ctypes
в Windows, теперь разрешены более безопасно. Только системные пути, каталог, содержащий файл DLL или PYD, и каталоги, добавленные вместе сadd_dll_directory()
, являются найденный для зависимостей времени загрузки. В частности,PATH
и текущий рабочий каталог больше не используются, и изменения в них больше не будут влиять на нормальное разрешение DLL. Если ваше заявление полагается на эти механизмы, вы должны проверить наadd_dll_directory()
и если это существует, используйте его, чтобы добавить ваш каталог DLLs, загружая вашу библиотеку. Обратите внимание, что пользователи Windows 7 должны будут гарантировать, что Windows Update KB2533623 был установлен (это также проверено инсталлятором). (Предоставлено Steve Dower в bpo-36085. - Заголовочные файлы и функции, связанные с pgen, были удалены после замены их чистой Python реализацией. (Внесено Pablo Galindo в bpo-36623.)
types.CodeType
имеет новый параметр во второй позиции конструктора (posonlyargcount) для поддержки аргументов только для позиций, определенных в PEP 570. Первый аргумент (argcount) теперь представляет общее число позиционных аргументов (включая только позиционные аргументы). Новыйreplace()
методtypes.CodeType
может быть используемый, чтобы сделать код соответствующим требованиям завтрашнего дня.
Изменения в API C¶
PyCompilerFlags
структура получила новое поле cf_feature_version. Она должена быть инициализирован дляPY_MINOR_VERSION
. Поле игнорируется по умолчанию и имеет значение используемый тогда и только тогда, когда флагPyCF_ONLY_AST
установлен в cf_flags. (Представлен Guido van Rossum в bpo-35766.)Функция
PyEval_ReInitThreads()
удалена из API C. Вместо этого его не следует называть явно использоватьPyOS_AfterFork_Child()
. (Представлен Victor Stinner в bpo-36728.В Unix расширения C больше не связаны с libpython, кроме Android и Cygwin. Когда Python встроен,
libpython
должен быть загружен неRTLD_LOCAL
, аRTLD_GLOBAL
вместо этого. Ранее, используяRTLD_LOCAL
, было уже не возможно загрузить расширения C, которые не были связаны сlibpython
, как расширения C стандартной библиотеки, построенной*shared*
разделомModules/Setup
. (Представлен Victor Stinner в bpo-21536.)Использование вариантов
#
форматов в парсинг или сборочным значением (напримерPyArg_ParseTuple()
,Py_BuildValue()
,PyObject_CallFunction()
, и т.д.) без определенногоPY_SSIZE_T_CLEAN
поднимаетDeprecationWarning
теперь. Он будет удален в 3.10 или 4.0. Прочитайте Анализ аргументов и сборка значений для детали. (Внесена Inada Naoki в bpo-36381.)Сущности выделенных кучой типов (например, созданные с
PyType_FromSpec()
) содержат ссылку на объект-тип. Увеличение справочного количества этих объектов типа было перемещено изPyType_GenericAlloc()
в больше функций низкоуровневое: c:func:PyObject_Init иPyObject_INIT()
. Это делает созданный черезPyType_FromSpec()
типов, ведут себя как другой классы в управляемом код.Статически распределенные типы не затрагиваются.
Для подавляющего большинства случаев не должно быть побочных эффектов. Однако типы, которые вручную увеличивают число ссылок после выделения сущность (возможно, для работы вокруг ошибки), теперь могут стать бессмертными. Чтобы избежать этого, эти классы должны назвать Py_DECREF на объекте типа во время освобождения сущность.
Чтобы правильно перенести эти типы в 3.8, примените следующие изменения:
Удалён
Py_INCREF
на объекте типа после распределения сущность - если таковые имеются. Это может произойти послеЭто может произойти после вызова
PyObject_New()
,PyObject_NewVar()
,PyObject_GC_New()
,PyObject_GC_NewVar()
или любой другой пользовательский аллокатор, который используетPyObject_Init()
илиPyObject_INIT()
.Пример:
static foo_struct * foo_new(PyObject *type) { foo_struct *foo = PyObject_GC_New(foo_struct, (PyTypeObject *) type); if (foo == NULL) return NULL; #if PY_VERSION_HEX < 0x03080000 // Workaround for Python issue 35810; no longer necessary in Python 3.8 PY_INCREF(type) #endif return foo; }
static void foo_dealloc(foo_struct *instance) { PyObject *type = Py_TYPE(instance); PyObject_GC_Del(instance); #if PY_VERSION_HEX >= 0x03080000 // This was not needed before Python 3.8 (Python issue 35810) Py_DECREF(type); #endif }
Убедитесь, что все пользовательские функции
tp_dealloc
выделенных типов уменьшают количество ссылок типа.Пример:
static void foo_dealloc(foo_struct *instance) { PyObject *type = Py_TYPE(instance); PyObject_GC_Del(instance); #if PY_VERSION_HEX >= 0x03080000 // This was not needed before Python 3.8 (Python issue 35810) Py_DECREF(type); #endif }
(Представлен Эдди Элизондо в bpo-35810.
для MSVC реализован макрос
Py_DEPRECATED()
. Макрос должен быть помещен перед именем символа.Пример:
Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);
(Представлен Zackery Spytz в bpo-33407.)
Интерпретатор больше не поддерживает двоичную совместимость типов расширений между выпусками компонентов.
PyTypeObject
, экспортируемые сторонним модулем расширения, должны иметь все слоты, ожидаемые в текущей версии Python, including:c:member:~PyTypeObject.tp_finalize (Py_TPFLAGS_HAVE_FINALIZE
больше не проверяется перед чтениемtp_finalize
).(Представлен Antoine Pitrou в bpo-32388.
Теперь функции
PyNode_AddChild()
иPyParser_AddToken()
принимают два дополнительныхint
аргумента end_lineno и end_col_offset.Файл
libpython38.a
, позволяющий инструментам MinGW связываться непосредственно сpython38.dll
, больше не входит в обычный дистрибутив Windows. Если требуется этот файл, он может быть создан с помощью инструментовgendef
иdlltool
, которые являются частью пакета binutils MinGW:gendef - python38.dll > tmp.def dlltool --dlname python38.dll -- def tmp.ef -- output-lib libpython38.a
Расположение установленного
pythonXY.dll
будет зависеть от параметров установки и версии и языка Windows. Дополнительные сведения см. в разделе Использование Python в Windows. Полученная библиотека должна быть помещена в тот же каталог, что иpythonXY.lib
, который обычно является каталогомlibs
при установке Python.(Представлен Steve Dower в bpo-37351.)
Изменения байткода CPython¶
Цикл интерпретатора был упрощен за счет перемещения логики распаковки стека блоков в компилятор. Компилятор выдает теперь явные инструкции по настройке стека значений и вызову код очистки для
break
,continue
иreturn
.Сняты коды операций
BREAK_LOOP
,CONTINUE_LOOP
,SETUP_LOOP
иSETUP_EXCEPT
. Добавлены новые коды операцийROT_FOUR
,BEGIN_FINALLY
,CALL_FINALLY
иPOP_FINALLY
. Изменило поведениеEND_FINALLY
иWITH_CLEANUP_START
.(Вклад Mark Shanno, Antoine Pitrou и Serhiy Storchaka в bpo-17611.
Добавленный новый opcode
END_ASYNC_FOR
для обработки исключений поднял, ожидая следующего предмета в петлеasync for
. (Представлен Serhiy Storchaka в bpo-33041.Теперь
MAP_ADD
ожидает значение как первый элемент в стеке, а ключ - как второй элемент. Это изменение было сделано, так что ключ всегда оценивается перед значением в словарных толкованиях, как предложено PEP 572. (Представлен Jörn Heissler в bpo-35224.)
Демонстрации и инструменты¶
Добавлен сценарий бенчмарка для синхронизации различных способов доступа к
переменным: Tools/scripts/var_access_benchmark.py
. (Представлен
Raymond Hettinger в bpo-35884.)
Ниже приводится краткая информация о повышении производительности с Python 3.3:
Python version 3.3 3.4 3.5 3.6 3.7 3.8
-------------- --- --- --- --- --- ---
Variable and attribute read access:
read_local 4.0 7.1 7.1 5.4 5.1 3.9
read_nonlocal 5.3 7.1 8.1 5.8 5.4 4.4
read_global 13.3 15.5 19.0 14.3 13.6 7.6
read_builtin 20.0 21.1 21.6 18.5 19.0 7.5
read_classvar_from_class 20.5 25.6 26.5 20.7 19.5 18.4
read_classvar_from_instance 18.5 22.8 23.5 18.8 17.1 16.4
read_instancevar 26.8 32.4 33.1 28.0 26.3 25.4
read_instancevar_slots 23.7 27.8 31.3 20.8 20.8 20.2
read_namedtuple 68.5 73.8 57.5 45.0 46.8 18.4
read_boundmethod 29.8 37.6 37.9 29.6 26.9 27.7
Variable and attribute write access:
write_local 4.6 8.7 9.3 5.5 5.3 4.3
write_nonlocal 7.3 10.5 11.1 5.6 5.5 4.7
write_global 15.9 19.7 21.2 18.0 18.0 15.8
write_classvar 81.9 92.9 96.0 104.6 102.1 39.2
write_instancevar 36.4 44.6 45.8 40.0 38.9 35.5
write_instancevar_slots 28.7 35.6 36.1 27.3 26.6 25.7
Data structure read access:
read_list 19.2 24.2 24.5 20.8 20.8 19.0
read_deque 19.9 24.7 25.5 20.2 20.6 19.8
read_dict 19.7 24.3 25.7 22.3 23.0 21.0
read_strdict 17.9 22.6 24.3 19.5 21.2 18.9
Data structure write access:
write_list 21.2 27.1 28.5 22.5 21.6 20.0
write_deque 23.8 28.7 30.1 22.7 21.8 23.5
write_dict 25.9 31.4 33.3 29.3 29.2 24.7
write_strdict 22.9 28.4 29.9 27.5 25.2 23.1
Stack (or queue) operations:
list_append_pop 144.2 93.4 112.7 75.4 74.2 50.8
deque_append_pop 30.4 43.5 57.0 49.4 49.2 42.5
deque_append_popleft 30.8 43.7 57.3 49.7 49.7 42.8
Timing loop:
loop_overhead 0.3 0.5 0.6 0.4 0.3 0.3
Оценки измерялись на Intel® Core™ i7-4960HQ processor, работающем на macOS 64 битами, строит найденный в python.org. Сценарий тестирования отображает время в наносекундах.
Заметные изменения в Python 3.8.1¶
Из-за значительных проблем безопасности параметр reuse_address asyncio.loop.create_datagram_endpoint()
больше
не поддерживается. Это связано с поведением параметра сокета SO_REUSEADDR
в
UDP. Для получения дополнительной информации см. документацию для loop.create_datagram_endpoint()
.
(Вклад Kyle Stanley, Antoine Pitrou и Yury Selivanov в bpo-37228.)
Заметные изменения в Python 3.8.2¶
Исправлена регрессия с ignore
колбэк shutil.copytree()
. Типы аргументов
теперь снова являются str и List[str]. (Вклад Manuel Barkhau и Giampaolo Rodola в bpo-39390.)
Заметные изменения в Python 3.8.3¶
Постоянные значения будущих флагов в модуле __future__
обновляются для
предотвращения конфликтов с флагами компилятора. Ранее PyCF_ALLOW_TOP_LEVEL_AWAIT
конфликтовал с CO_FUTURE_DIVISION
. (Предоставлено Batuhan Taskaya в bpo-39562)
Заметные изменения в Python 3.8.8¶
Более ранние версии Python позволяли использовать как ;
, так и &
в
качестве разделителей параметров запроса в urllib.parse.parse_qs()
и
urllib.parse.parse_qsl()
. Из-за проблем безопасности и в соответствии с
новыми рекомендациями W3C этот параметр был изменён, чтобы разрешить только один
разделительный ключ. По умолчанию используется &
. Это изменение также
влияет на cgi.parse()
и cgi.parse_multipart()
, поскольку они
используют затронутые функции внутри системы. Для получения более подробной
информации, пожалуйста, ознакомьтесь с их соответствующей документацией. (Вклад
Адама Гольдшмидта, Сентила Кумарана и Кена Джина в bpo-42967.)