Что нового в Python 3.8¶
- Редактор:
Раймонд Хеттингер
В этой статье описываются новые возможности Python 3.8 по сравнению с версией 3.7. Версия Python 3.8 была выпущена 14 октября 2019 года. Более подробную информацию смотрите в changelog.
Краткое описание - Основные моменты выпуска¶
Новые возможности¶
Выражения присваивания¶
Появился новый синтаксис :=
, который присваивает значения переменным как части более крупного выражения. Его ласково называют «оператором моржа» из-за его сходства с the eyes and tusks of a walrus.
В этом примере выражение присваивания помогает избежать повторного вызова 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, которые вычисляют значение для проверки завершения цикла, а затем снова нуждаются в том же значении в теле цикла:
# 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]
Постарайтесь ограничить использование оператора walrus для очистки обращений, которые снижают сложность и улучшают читаемость.
Смотрите PEP 572 для получения полного описания.
(Автор: Эмили Морхаус в bpo-35224.)
Параметры только для определения местоположения¶
Появился новый синтаксис параметра функции /
, указывающий на то, что некоторые параметры функции должны быть указаны позиционно и не могут использоваться в качестве аргументов ключевых слов. Это то же самое обозначение, что и help()
для функций C, аннотированных с помощью инструмента Ларри Хастингса Argument Clinic.
В следующем примере параметры 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 cannot be a keyword argument
f(10, 20, 30, 40, 50, f=60) # e must be a keyword argument
Одним из вариантов использования этой нотации является то, что она позволяет чисто функциональным функциям Python полностью имитировать поведение существующих функций, закодированных на C. Например, встроенная функция divmod()
не принимает аргументы по ключевым словам:
def divmod(a, b, /):
"Emulate the built in divmod() function"
return (a // b, a % b)
Другой вариант использования - исключить аргументы ключевого слова, когда имя параметра не является полезным. Например, встроенная функция len()
имеет сигнатуру len(obj, /)
. Это исключает неудобные вызовы, такие как:
len(obj='hello') # The "obj" keyword argument impairs readability
Еще одно преимущество пометки параметра как позиционного заключается в том, что это позволяет изменять имя параметра в будущем без риска взлома клиентского кода. Например, в модуле 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 and b are used in two ways
10 20 {'a': 1, 'b': 2, 'c': 3}
Это значительно упрощает реализацию функций и методов, которым необходимо принимать аргументы с произвольными ключевыми словами. Например, вот выдержка из кода в модуле collections
:
class Counter(dict):
def __init__(self, iterable=None, /, **kwds):
# Note "iterable" is a possible keyword argument
Смотрите PEP 570 для получения полного описания.
(Автор: Пабло Галиндо в bpo-36540.)
Кэш параллельной файловой системы для скомпилированных файлов байт-кода¶
Новый параметр PYTHONPYCACHEPREFIX
(также доступен как -X
pycache_prefix
) настраивает неявный кеш байт-кода для использования отдельного дерева параллельной файловой системы, а не подкаталогов по умолчанию __pycache__
в каждом исходном каталоге.
Местоположение кэша указано в разделе sys.pycache_prefix
(None
указывает местоположение по умолчанию в подкаталогах __pycache__
).
(Автор: Карл Мейер в статье bpo-33499.)
Отладочная сборка использует тот же ABI, что и release build¶
Python теперь использует один и тот же ABI, независимо от того, собран ли он в режиме выпуска или отладки. В Unix, когда Python собран в режиме отладки, теперь можно загружать расширения C, созданные в режиме выпуска, и расширения C, созданные с использованием стабильного ABI.
Релизные сборки и debug builds теперь совместимы с ABI: определение макроса Py_DEBUG
больше не подразумевает использование макроса Py_TRACE_REFS
, что приводит к единственной несовместимости с ABI. Макрос Py_TRACE_REFS
, который добавляет функцию sys.getobjects()
и переменную окружения PYTHONDUMPREFS
, можно задать с помощью новой опции построения ./configure --with-trace-refs
. (Автор: Виктор Стиннер в bpo-36465.)
В Unix расширения C больше не связаны с libpython, за исключением Android и Cygwin. Теперь статически связанный Python может загружать расширение C, созданное с использованием общей библиотеки Python. (Автор: Виктор Стиннер в bpo-21536.)
В Unix, когда Python собран в режиме отладки, import теперь также ищет расширения C, скомпилированные в режиме выпуска, и расширения C, скомпилированные со стабильным ABI. (Автор: Виктор Стиннер в bpo-36722).
Чтобы внедрить Python в приложение, необходимо передать новую опцию --embed
в python3-config --libs --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, случаи которых обрабатываются скриптом); это изменение намеренно несовместимо с обратной связью. (Автор: Виктор Стиннер в bpo-36721.)
поддержка f-строк =
для самодокументирования выражений и отладки¶
Добавлен спецификатор =
в f-strings. 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-string format specifiers позволяют лучше контролировать способ отображения результата выражения:
>>> 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
(Материалы предоставлены Эриком В. Смитом и Ларри Хастингсом в bpo-36817.)
PEP 578: Перехватчики аудита среды выполнения Python¶
В PEP добавлены функции аудита и Verified Open Hook. Оба они доступны как в Python, так и в машинном коде, что позволяет приложениям и фреймворкам, написанным на чистом коде Python, получать дополнительные уведомления, а также позволяет разработчикам внедрений или системным администраторам развертывать сборки Python, в которых всегда включен аудит.
Смотрите PEP 578 для получения более подробной информации.
PEP 587: Конфигурация инициализации Python¶
PEP 587 добавляет новый C API для настройки инициализации Python, обеспечивая более точный контроль над всей конфигурацией и улучшенную отчетность об ошибках.
Новые структуры:
Новые функции:
Этот PEP также добавляет поля _PyRuntimeState.preconfig
(PyPreConfig
тип) и PyInterpreterState.config
(PyConfig
тип) к этим внутренним структурам. PyInterpreterState.config
становится новой ссылкой конфигурация, заменяющая глобальные переменные конфигурации и другие частные переменные.
Документацию смотрите в разделе Python Initialization Configuration.
Смотрите PEP 587 для получения полного описания.
(Автор: Виктор Стиннер в bpo-36763.)
PEP 590: Vectorcall: протокол быстрого вызова для CPython¶
Протокол векторных вызовов добавлен в Python/C API. Он предназначен для формализации существующих оптимизаций, которые уже были выполнены для различных классов. Любой static type, реализующий вызываемый объект, может использовать этот протокол.
В настоящее время это предварительный вариант. Цель состоит в том, чтобы сделать его полностью общедоступным в Python 3.9.
Смотрите PEP 590 для получения полного описания.
(Авторы: Йерун Демейер, Марк Шеннон и Петр Викторин в статье bpo-36974.)
Протокол Pickle 5 с внешними буферами данных¶
Когда pickle
используется для передачи больших объемов данных между процессами Python, чтобы воспользоваться преимуществами многоядерной или многомашинной обработки, важно оптимизировать передачу за счет уменьшения количества копий в памяти и, возможно, применения пользовательских методов, таких как сжатие, зависящее от данных.
Протокол pickle
5 вводит поддержку внеполосных буферов, в которых PEP 3118-совместимые данные могут передаваться отдельно от основного потока pickle, по усмотрению коммуникационного уровня.
Смотрите PEP 574 для получения полного описания.
(Автор: Антуан Питру в статье bpo-36785.)
Другие языковые изменения¶
Утверждение
continue
было недопустимым в предложенииfinally
из-за проблемы с реализацией. В Python 3.8 это ограничение было снято. (Добавлено Сергеем Сторчакой в bpo-32489.)Типы
bool
,int
, иfractions.Fraction
теперь имеют методas_integer_ratio()
, аналогичный тому, который используется вfloat
иdecimal.Decimal
. Это небольшое расширение API позволяет написатьnumerator, denominator = x.as_integer_ratio()
и заставить его работать с несколькими числовыми типами. (Авторы: Лиза Роуч в bpo-33073 и Раймонд Хеттингер в bpo-37819).Конструкторы
int
,float
иcomplex
теперь будут использовать специальный метод__index__()
, если он доступен, а соответствующий метод__int__()
,__float__()
или__complex__()
недоступен. (Автор - Сергей Сторчака в 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
(Материалы предоставлены Джонатаном Юнисом и Сергеем Сторчакой в bpo-30688.)
Dick и dictviews не могут быть повторены в обратном порядке вставки, рейтинг
reversed()
. (Автор: Реми Лапейр в bpo-33462.)Синтаксис, разрешенный для имен ключевых слов в вызовах функций, был дополнительно ограничен. В частности,
f((keyword)=arg)
больше не допускается. Никогда не предполагалось, что в левой части термина назначения аргумента ключевого слова должно быть что-то большее, чем просто имя. (Автор: Бенджамин Питерсон в статье bpo-34641.)Обобщенная итеративная распаковка в операторах
yield
иreturn
больше не требует заключения в круглые скобки. Это приводит синтаксис yield и return в большее соответствие с обычным синтаксисом присваивания:>>> def parse(family): lastname, *members = family.split() return lastname.upper(), *members >>> parse('simpsons homer marge bart lisa maggie') ('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'maggie')
(Материалы предоставлены Дэвидом Катбертом и Джорданом Чепменом в bpo-32117.)
Когда в коде пропущена запятая, например,
[(10, 20) (30, 40)]
, компилятор отображаетSyntaxWarning
с полезным предложением. Это улучшает работу сTypeError
, указывающим на то, что первый кортеж не был вызван. (Автор - Сергей Сторчака в bpo-15248.)Арифметические операции между подклассами объектов
datetime.date
илиdatetime.datetime
иdatetime.timedelta
теперь возвращают экземпляр подкласса, а не базового класса. Это также влияет на возвращаемый тип операций, реализация которых (прямо или косвенно) использует арифметикуdatetime.timedelta
, например,astimezone()
. (Добавлено Полом Гансслом в bpo-32417.)Когда интерпретатор Python прерывается нажатием Ctrl-C (SIGINT) и результирующее исключение
KeyboardInterrupt
не перехватывается, процесс Python завершает работу с помощью сигнала SIGINT или с правильным кодом завершения, чтобы вызывающий процесс мог определить, что он прекратил работу из-за нажатия Ctrl-C. Оболочки в POSIX и Windows используют это для корректного завершения работы скриптов в интерактивных сессиях. (Предоставлено Google через Грегори П. Смита в 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'
(Автор: Виктор Стиннер в bpo-37032.)
Для целых чисел функция с тремя аргументами
pow()
теперь допускает отрицательное значение показателя степени в случае, когда основание относительно простого значения модуля. Затем вычисляется модуль, обратный основному, когда показатель равен-1
, и соответствующая степень этого обратного для других отрицательных показателей. Например, чтобы вычислить modular multiplicative inverse из 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
(Автор: Марк Дикинсон в 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'}
(Автор: Йорн Хайслер в статье bpo-35224.)
Метод
object.__reduce__()
теперь может возвращать кортеж длиной от двух до шести элементов. Ранее ограничением было пять. Новый необязательный шестой элемент является вызываемым с сигнатурой(obj, state)
. Это позволяет напрямую управлять поведением конкретного объекта при обновлении состояния. Если нет None, то этот вызываемый объект будет иметь приоритет над методом объекта__setstate__()
. (Материалы предоставлены Пьером Глейзером и Оливье Гризелем в 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')]
(Авторы: Барри Уоршоу и Джейсон Р. Кумбс в bpo-34632.)
Улучшенные модули¶
аст¶
Узлы AST теперь имеют атрибуты end_lineno
и end_col_offset
, которые указывают точное местоположение конца узла. (Это относится только к узлам, имеющим атрибуты lineno
и col_offset
.)
Новая функция ast.get_source_segment()
возвращает исходный код для определенного узла AST.
(Автор: Иван Левкивский в bpo-33416.)
Функция ast.parse()
имеет несколько новых флагов:
type_comments=True
заставляет его возвращать текст комментариев типа PEP 484 и PEP 526, связанных с определенными узлами AST;mode='func_type'
может использоваться для анализа PEP 484 «комментариев типа подписи» (возвращаемых для узлов functiondefinitionAST);feature_version=(3, N)
позволяет указать более раннюю версию Python 3. Например,feature_version=(3, 4)
будет обрабатыватьasync
иawait
как незарезервированные слова.
(Автор: Гвидо ван Россум в статье bpo-35766.)
асинхронный¶
asyncio.run()
перешел от временного API к стабильному. Эта функция может использоваться для выполнения coroutine и возврата результата при автоматическом управлении циклом обработки событий. Например:
import asyncio
async def main():
await asyncio.sleep(0)
return 42
asyncio.run(main())
Это примерно эквивалентно:
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.
(Автор: Юрий Селиванов в статье 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
(Автор: Юрий Селиванов в статье bpo-37028.)
Исключение asyncio.CancelledError
теперь наследуется от BaseException
, а не от Exception
и больше не наследуется от concurrent.futures.CancelledError
. (Добавлено Юрием Селивановым в bpo-32528.)
В Windows цикл обработки событий по умолчанию теперь равен ProactorEventLoop
. (Добавлено Виктором Стиннером в bpo-34687.)
ProactorEventLoop
теперь также поддерживается UDP. (Добавлено Адамом Мейли и Эндрю Светловым в bpo-29883.)
ProactorEventLoop
теперь можно прервать нажатием кнопки KeyboardInterrupt
(«CTRL+C»). (Добавлено Владимиром Матвеевым в bpo-23057.)
Добавлено asyncio.Task.get_coro()
без учета обернутой сопрограммы в asyncio.Task
. (Добавлено Алексом Гренхольмом в bpo-36999.)
Задачам Asyncio теперь можно присваивать имена, либо передавая аргумент ключевого слова name
в asyncio.create_task()
, либо в метод цикла обработки событий create_task()
, либо вызывая метод set_name()
для объекта task. Название задачи отображается в repr()
выходных данных asyncio.Task
, а также может быть получено с помощью метода get_name()
. (Добавлено Алексом Гренхольмом в bpo-34270.)
Добавлена поддержка Happy Eyeballs в asyncio.loop.create_connection()
. Чтобы задать поведение, были добавлены два новых параметра: happy_eyeballs_delay и interleave. Алгоритм Happy Eyeballs улучшает скорость отклика в приложениях, поддерживающих IPv4 и IPv6, за счет одновременного подключения с использованием обоих. (Автор: twisteroid ambassador в bpo-33530).
встроенные модули¶
Встроенная функция compile()
была улучшена, чтобы принимать флаг ast.PyCF_ALLOW_TOP_LEVEL_AWAIT
. С переданным этим новым флагом compile()
будут разрешены конструкции верхнего уровня await
, async for
и async with
, которые обычно считаются недопустимым синтаксисом. Затем может быть возвращен объект асинхронного кода, помеченный флагом CO_COROUTINE
. (Автор - Маттиас Буссонье в статье bpo-34616)
коллекции¶
Метод _asdict()
для collections.namedtuple()
теперь возвращает dict
вместо collections.OrderedDict
. Это работает, потому что обычные диктовки гарантируют упорядочение, начиная с версии Python 3.7. Если требуются дополнительные функции OrderedDict
, предлагаемое исправление заключается в приведении результата к желаемому типу: OrderedDict(nt._asdict())
. (Материал подготовлен Раймондом Хеттингером в bpo-35864.)
Профайл¶
Класс cProfile.Profile
теперь можно использовать в качестве контекстного менеджера. Создайте профиль блока кода, выполнив:
import cProfile
with cProfile.Profile() as profiler:
# code to be profiled
...
(Автор: Скотт Сандерсон в статье bpo-29235.)
csv-файл¶
csv.DictReader
теперь возвращает значения dict
вместо collections.OrderedDict
. Инструмент теперь работает быстрее и использует меньше памяти, сохраняя при этом порядок полей. (Автор: Майкл Селик в статье bpo-34003.)
проклятия¶
Добавлена новая переменная, содержащая структурированную информацию о версии для базовой библиотеки ncurses: ncurses_version
. (Добавлено Сергеем Сторчакой в bpo-31680.)
типы данных¶
В Windows, CDLL
и подклассы теперь принимают параметр winmode, чтобы указать флаги для базового вызова LoadLibraryEx
. Флаги по умолчанию установлены для загрузки зависимостей DLL только из надежных мест, включая путь, по которому хранится библиотека DLL (если для загрузки исходной библиотеки DLL используется полный или частичный путь), и пути, добавленные с помощью add_dll_directory()
. (Автор: Стив Дауэр в статье bpo-36085.)
дата и время¶
Добавлены новые альтернативные конструкторы datetime.date.fromisocalendar()
и datetime.datetime.fromisocalendar()
, которые создают объекты date
и datetime
соответственно из года ISO, номера недели и дня недели; они являются обратными для каждого класса isocalendar
способ. (Автор: Пол Ганссл в bpo-36004.)
функциональные средства¶
functools.lru_cache()
теперь можно использовать как обычный декоратор, а не как функцию, возвращающую декоратор. Таким образом, теперь поддерживаются оба этих параметра:
@lru_cache
def f(x):
...
@lru_cache(maxsize=256)
def f(x):
...
(Материал подготовлен Раймондом Хеттингером в 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)
(Автор: Карл Мейер в bpo-21145)
Добавлен новый functools.singledispatchmethod()
декоратор, который преобразует методы в generic functions с помощью single dispatch:
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]
(Автор: Итан Смит в bpo-32380)
gc (общий сбор)¶
get_objects()
теперь может получать необязательный параметр generation, указывающий поколение, из которого будут получены объекты. (Добавлено Пабло Галиндо в bpo-36016.)
получить текст¶
Добавлено pgettext()
и его варианты. (Авторы: Франц Гласнер, Эрик Араужо и Шерил Сабелла в bpo-2504.)
gzip-файл¶
Добавлен параметр mtime в gzip.compress()
для обеспечения воспроизводимости результатов. ((Добавлено Го Цит Тео в bpo-34898.)
Исключение BadGzipFile
Теперь генерируется вместо OSError
для определенных типов недействительных или поврежденных файлов gzip. ((Материалы предоставлены Филипом Грущинским, Мишель Орру и Закери Спитцем в bpo-6584.)
ХОЛОСТОЙ ход и idlelib¶
Вывод в N строках (по умолчанию 50) сокращается до размера кнопки. N можно изменить в разделе PyShell на странице «Общие» диалогового окна настроек. Меньшее количество строк, но, возможно, и более длинных, можно сжать, щелкнув правой кнопкой мыши на выводе. Сжатый вывод можно развернуть на месте, дважды щелкнув по кнопке, или перенести в буфер обмена, или в отдельное окно, щелкнув по кнопке правой кнопкой мыши. (Добавлено Tal Einat в bpo-1529353.)
Добавьте «Запустить настроенный» в меню «Выполнить», чтобы запустить модуль с настроенными настройками. Все введенные аргументы командной строки добавляются в файл sys.argv. Они также отображаются в окне для следующего настроенного запуска. Можно также отключить обычный перезапуск основного модуля оболочки. (Авторы: Шерил Сабелла, Терри Джен Риди и другие в bpo-5680 и bpo-37627.)
Добавлены дополнительные номера строк для неактивных окон редактора. Окна открываются без номеров строк, если не указано иное на вкладке Общие диалогового окна настройки. Номера строк для существующего окна отображаются и скрываются в меню Параметров. (Материалы предоставлены Тал Эйнат и Саймадхавом Хебликаром в bpo-17535.)
Для преобразования строк Python в объекты Tcl теперь используется собственная кодировка операционной системы. Это позволяет IDLE работать с эмодзи и другими символами, отличными от BMP. Эти символы можно отображать или копировать и вставлять в буфер обмена или из него. Преобразование строк из Tcl в Python и обратно теперь никогда не приводит к сбоям. (Многие люди работали над этим в течение восьми лет, но в конце концов проблема была решена Сергеем Сторчакой в bpo-13153.)
Новое в версии 3.8.1:
Добавлена возможность отключить мигание курсора. (Автор: Закери Спитц в bpo-4603.)
Клавиша Escape теперь закрывает незанятые окна завершения. (Добавлено Джонни Наджерой в bpo-38944.)
Приведенные выше изменения были перенесены в версии обслуживания 3.7.
Добавьте ключевые слова в список заполнения названия модуля. (Автор: Терри Дж. Риди в bpo-37765.)
проверить¶
Функция 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)
(Материал подготовлен Раймондом Хеттингером в bpo-36326.)
ио¶
В режиме разработки (-X
env
) и в debug build финализатор io.IOBase
теперь регистрирует исключение, если метод close()
завершается ошибкой. Исключение по умолчанию автоматически игнорируется при сборке релиза. (Добавлено Виктором Стиннером в bpo-18748.)
итеративные инструменты¶
Функция itertools.accumulate()
добавила аргумент ключевого слова option initial для указания начального значения:
>>> from itertools import accumulate
>>> list(accumulate([10, 5, 30, 15], initial=1000))
[1000, 1010, 1015, 1045, 1060]
(Автор: Лиза Роуч в bpo-34659.)
json.инструмент¶
Добавьте опцию --json-lines
, чтобы анализировать каждую строку ввода как отдельный объект JSON. ((Добавлено Weipeng Hong в bpo-31553.)
регистрация¶
Добавлен аргумент ключевого слова force в logging.basicConfig()
При значении true все существующие обработчики, подключенные к корневому регистратору, удаляются и закрываются перед выполнением конфигурации, указанной в других аргументах.
Это решает давнюю проблему. После вызова логгера или функции basicConfig() последующие вызовы функции basicConfig() автоматически игнорировались. Это затрудняло обновление, экспериментирование или обучение различным параметрам конфигурации ведения журнала с помощью интерактивного приглашения или записной книжки Jupyter.
((Предложено Раймондом Хеттингером, реализовано Донхи На и рассмотрено Винаем Саджипом в bpo-33897.)
математика¶
Добавлена новая функция math.dist()
для вычисления евклидова расстояния между двумя точками. (Добавлено Раймондом Хеттингером в bpo-33089.)
Расширена функция math.hypot()
для обработки нескольких измерений. Ранее она поддерживала только двумерный случай. (Добавлено Раймондом Хеттингером в bpo-33089).
Добавлена новая функция, math.prod()
, аналогичная функции sum()
, которая возвращает произведение начального значения (по умолчанию: 1) на повторяемое число:
>>> prior = 0.8
>>> likelihoods = [0.625, 0.84, 0.30]
>>> math.prod(likelihoods, start=prior)
0.126
(Автор: Пабло Галиндо в 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
(Авторы: Яш Аггарвал, Келлер Фукс, Сергей Сторчака и Раймонд Хеттингер в статье 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
(Автор: Марк Дикинсон в bpo-36887.)
Функция math.factorial()
больше не принимает аргументы, которые не являются int-подобными. (Добавлено Пабло Галиндо в bpo-33083.)
ммап¶
В классе mmap.mmap
теперь есть метод madvise()
для доступа к системному вызову madvise()
. (Добавлено Закери Спитцем в bpo-32941.)
многопроцессорная обработка¶
Добавлен новый модуль multiprocessing.shared_memory
. (Автор - Дэвин Поттс в bpo-35813.)
В Mac OS по умолчанию теперь используется метод spawn start. (Автор: Виктор Стиннер в bpo-33725.)
ос¶
Добавлена новая функция add_dll_directory()
в Windows для предоставления дополнительных путей поиска собственных зависимостей при импорте модулей расширения или загрузке библиотек DLL с помощью ctypes
. (Добавлено Стивом Дауэром в bpo-36085.)
Была добавлена новая функция os.memfd_create()
для завершения системного вызова memfd_create()
. (Авторы - Закери Спитц и Кристиан Хеймс в статье 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()
, теперь может обрабатывать соединения как ссылки.
(Автор: Стив Дауэр в статье bpo-37834.)
os.путь¶
os.path
функции, возвращающие логический результат типа exists()
, lexists()
, isdir()
, isfile()
, islink()
, и ismount()
теперь верните False
вместо того, чтобы поднимать ValueError
или его подклассы UnicodeEncodeError
и UnicodeDecodeError
для путей, которые содержат символы или байты, непредставимые на уровне операционной системы. (Автор - Сергей Сторчака в bpo-33721.)
expanduser()
в Windows теперь используется переменная окружения USERPROFILE
и не используется HOME
, которая обычно не устанавливается для обычных учетных записей пользователей. (Автор Энтони Соттайл в bpo-36264.)
isdir()
в Windows больше не возвращает True
для ссылки на несуществующий каталог.
realpath()
в Windows теперь разрешаются точки повторного анализа, включая символические ссылки и переходы между каталогами.
(Автор: Стив Дауэр в статье bpo-37834.)
файл пути¶
pathlib.Path
методы, возвращающие логический результат типа exists()
, is_dir()
, is_file()
, is_mount()
, is_symlink()
, is_block_device()
, is_char_device()
, is_fifo()
, is_socket()
теперь возвращают False
вместо того, чтобы вызывать ValueError
или его подкласс UnicodeEncodeError
для путей, содержащих непредставимые символы на уровне операционной системы. (Автор: Сергей Сторчака в bpo-33721.)
Добавлен pathlib.Path.link_to()
, который создает жесткую ссылку, указывающую на путь. (Добавлено Джоанной Нанджекай в bpo-26978)
соленый огурец¶
pickle
расширения, подклассифицирующие оптимизированный для C Pickler
, теперь могут переопределять логику выбора функций и классов, определяя специальный метод reducer_override()
. (Материалы предоставлены Пьером Глейзером и Оливье Гризелем в bpo-35900.)
plistlib - список¶
Добавлены новые plistlib.UID
и включена поддержка чтения и записи двоичных списков plist, закодированных в NSKeyedArchiver. (Автор Джон Янзен в bpo-26707).
печать¶
Модуль pprint
добавил параметр sort_dicts к нескольким функциям. По умолчанию эти функции продолжают сортировать словари перед отображением или печатью. Однако, если для параметра sort_dicts установлено значение false, в словарях сохраняется порядок вставки ключей. Это может быть полезно для сравнения с вводимыми данными в формате 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'}
(Автор: Реми Лапейр в статье bpo-30670.)
py_compile скомпилировать¶
py_compile.compile()
теперь поддерживается беззвучный режим. (Добавлено Джоанной Нанджекай в bpo-22640.)
шлекс¶
Новая функция shlex.join()
действует как обратная shlex.split()
. (Добавлено Бо Бейлсом в bpo-32102.)
выключил¶
shutil.copytree()
теперь принимает новый аргумент ключевого слова dirs_exist_ok
. (Добавлено Джошем Бронсоном в bpo-20849.)
shutil.make_archive()
теперь по умолчанию используется современный формат pax (POSIX.1-2001) для новых архивов, чтобы улучшить переносимость и соответствие стандартам, унаследованный от соответствующего изменения в модуле tarfile
. (Предоставлено К.А.М. Герлахом в bpo-30661.)
shutil.rmtree()
в Windows теперь удаляются переходы между каталогами без предварительного рекурсивного удаления их содержимого. (Добавлено Стивом Дауэром в bpo-37834.)
разъем¶
Добавлены удобные функции create_server()
и has_dualstack_ipv6()
для автоматизации необходимых задач, обычно выполняемых при создании serversocket, включая прием подключений IPv4 и IPv6 к одному и тому же сокету. (Автор: Джампаоло Родола в bpo-17561.)
Функции socket.if_nameindex()
, socket.if_nametoindex()
, и socket.if_indextoname()
были реализованы в Windows. (Добавлено Закери Спитцем в bpo-37007).
протокол ssl¶
Добавлено post_handshake_auth
для включения и verify_client_post_handshake()
для инициализации аутентификации по протоколу TLS 1.3 после подтверждения связи. (Автор Кристиан Хеймс в bpo-34670).
статистика¶
Добавлен statistics.fmean()
как более быстрый вариант statistics.mean()
с плавающей запятой. (Авторы - Рэймонд Хеттингер и Стивен Д’Апрано в bpo-35904.)
Добавлено statistics.geometric_mean()
(Добавлено Раймондом Хеттингером в bpo-27181.)
Добавлен statistics.multimode()
, который возвращает список наиболее распространенных значений. (Добавлено Раймондом Хеттингером в bpo-35892.)
Добавлен statistics.quantiles()
, который делит данные или распределение на равновероятные интервалы (например, квартили, децили или процентили). (Добавлено Раймондом Хеттингером в bpo-36546.)
Добавлен statistics.NormalDist
, инструмент для создания нормальных распределений случайной величины и управления ими. (Добавлено Раймондом Хеттингером в 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()
). (Добавлено Виктором Стиннером в bpo-36829.)
архивный файл¶
Модуль tarfile
теперь по умолчанию использует современный формат pax (POSIX.1-2001) для новых архивов вместо предыдущего формата, специфичного для GNU. Это улучшает межплатформенную переносимость с помощью согласованной кодировки (UTF-8) в стандартизированном и расширяемом формате и дает ряд других преимуществ. (Автор: C.A.M. Герлах в bpo-36268).
нарезание резьбы¶
Добавьте новую функцию threading.excepthook()
, которая обрабатывает неперехваченное исключение threading.Thread.run()
. Ее можно переопределить, чтобы управлять обработкой неперехваченных исключений threading.Thread.run()
. (Автор: Виктор Стиннер в статье bpo-1230540.)
Добавьте новую функцию threading.get_native_id()
и атрибут native_id
в класс threading.Thread
. Они возвращают собственный интегральный идентификатор текущего потока, назначенный ядром. Эта функция доступна только на определенных платформах, смотрите get_native_id
для получения дополнительной информации. (Автор Джейк Теслер в bpo-36084).
обозначить¶
Модуль tokenize
теперь неявно выдает токен NEWLINE
при вводе данных, которые не содержат новой строки в конце. Такое поведение теперь соответствует тому, что выполняет внутренний токенизатор C. (Добавлено Аммаром Аскаром в bpo-33899.)
ткинтер¶
Добавлены методы selection_from()
, selection_present()
, selection_range()
и selection_to()
в классе tkinter.Spinbox
. (Автор: Джульетта Монсель в bpo-34829.)
Добавлен метод moveto()
в классе tkinter.Canvas
. (Добавлено Джульеттой Монсель в bpo-23831.)
В классе tkinter.PhotoImage
теперь есть методы transparency_get()
и transparency_set()
. (Добавлено Закери Спитцем в bpo-25451.)
время¶
Добавлены новые часы CLOCK_UPTIME_RAW
для mac OS 10.12 (автор Джоанна Нанджекай в bpo-35702).
печатание¶
Модуль typing
включает в себя несколько новых функций:
Тип словаря с типами для каждого ключа. Смотрите PEP 589 и
typing.TypedDict
. В Typedict используются только строковые ключи. По умолчанию требуется наличие каждого ключа. Укажите «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()
. Квалификатор final предписывает программе проверки статических типов ограничить создание подклассов, переопределение или переназначение:pi: Final[float] = 3.1415926536
Определения протоколов. Смотрите PEP 544,
typing.Protocol
иtyping.runtime_checkable()
. Простые азбуки, такие какtyping.SupportsInt
, теперь являются подклассамиProtocol
.Новый класс протокола
typing.SupportsIndex
.Новые функции
typing.get_origin()
иtyping.get_args()
.
данные в юникоде¶
Модуль unicodedata
был обновлен для использования версии Unicode 12.1.0.
Новая функция is_normalized()
может быть использована для проверки того, что строка имеет определенную нормальную форму, часто намного быстрее, чем при фактической нормализации строки. (Материалы предоставлены Максом Беленджером, Дэвидом Эврести и Грегом Прайсом в bpo-32285 и bpo-37966).
единичный тест¶
Добавлен AsyncMock
для поддержки асинхронной версии Mock
. Также добавлены соответствующие новые функции assert для тестирования. (Добавлено Лизой Роуч в bpo-26467).
Добавлены addModuleCleanup()
и addClassCleanup()
в модульный тест для поддержки очистки для setUpModule()
и setUpClass()
. (Добавлено Лизой Роуч в bpo-24412.)
Некоторые фиктивные функции assert теперь также выводят список реальных вызовов в случае сбоя. (Добавлено Петтером Страндмарком в bpo-35047.)
unittest
модуль получил поддержку сопрограмм, которые будут использоваться в качестве тестовых примеров с unittest.IsolatedAsyncioTestCase
. (Добавлено Андреем Светловым в 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
теперь включает в себя Activate.ps1
скрипт для активации виртуальных сред под управлением PowerShell Core 6.1 на всех платформах (добавлен Бреттом Кэнноном в bpo-32718).
слабая ссылка¶
Прокси-объекты, возвращаемые weakref.proxy()
, теперь поддерживают операторы умножения матриц @
и @=
в дополнение к другим числовым операторам. (Добавлено Марком Дикинсоном в bpo-36669.)
xml-код¶
В качестве защиты от DTD и поиска внешних объектов модули xml.dom.minidom
и xml.sax
больше не обрабатывают внешние объекты по умолчанию. (Автор Кристиан Хеймс в статье bpo-17239).
Методы .find*()
в модуле xml.etree.ElementTree
поддерживают поиск по шаблону, например, {*}tag
, который игнорирует пространство имен, и {namespace}*
, который возвращает все теги в заданном пространстве имен. (Автор: Стефан Бенель в статье bpo-28238.)
Модуль xml.etree.ElementTree
предоставляет новую функцию –xml.etree.ElementTree.canonicalize()
, которая реализует C14N 2.0. (Добавлена Стефаном Бенелем в bpo-13611).
Целевой объект xml.etree.ElementTree.XMLParser
может получать события объявления пространства имен с помощью новых методов обратного вызова start_ns()
и end_ns()
. Кроме того, целевой объект xml.etree.ElementTree.TreeBuilder
может быть сконфигурирован для обработки событий, связанных с комментариями, и инструкций по обработке, чтобы включить их в сгенерированное дерево. (Предоставлено Стефаном Бенелем в bpo-36676 и bpo-36673).
xmlrpc¶
xmlrpc.client.ServerProxy
теперь поддерживается необязательный аргумент ключевого слова headers для последовательности HTTP-заголовков, отправляемых с каждым запросом. Среди прочего, это позволяет перейти от базовой аутентификации по умолчанию к более быстрой аутентификации по сеансу. ((Материал подготовлен Седриком Криером в bpo-35153.)
Оптимизация¶
Модуль
subprocess
теперь может использовать функциюos.posix_spawn()
в некоторых случаях для повышения производительности. В настоящее время он используется только в macOS и Linux (с использованием glibc 2.24 или новее), если соблюдены все эти условия:close_fds имеет значение false;
параметры preexec_fn, pass_fds, cwd и start_new_session не заданы;
путь к исполняемому файлу содержит каталог.
(Материалы предоставлены Джоанной Нанджекай и Виктором Стиннером в bpo-35537.)
shutil.copyfile()
,shutil.copy()
,shutil.copy2()
,shutil.copytree()
иshutil.move()
использовать платформо-зависимые «быстрая копия» системные вызовы на Linux и macOS для того, чтобы скопировать файл более эффективно. «быстрое копирование» означает, что операция копирования выполняется внутри ядра, что позволяет избежать использования буферов пользовательского пространства в Python, как в «outfd.write(infd.read())
». В Windowsshutil.copyfile()
используется больший размер буфера по умолчанию (1 МБ вместо 16 КБ), и используется вариантshutil.copyfileobj()
, основанный наmemoryview()
. Ускорение копирования файла размером 512 МБ в пределах одного раздела составляет около +26% в Linux, +50% в macOS и +40% в Windows. Кроме того, значительно сокращается время работы процессора. Смотрите раздел Эффективные операции копирования, зависящие от платформы. (Добавлено Джампаоло Родолой в статье bpo-33671.)shutil.copytree()
использует функциюos.scandir()
, и все зависящие от нее функции копирования используют кэшированные значенияos.stat()
. Ускорение копирования каталога с 8000 файлами составляет около +9% в Linux, +20% в Windows и +30% в общем ресурсе Windows SMB. Кроме того, количество системных вызововos.stat()
сокращено на 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 байт. (Автор - Инада Наоки в bpo-33597.)uuid.UUID
теперь использует__slots__
, чтобы уменьшить объем занимаемой памяти. (Добавлено Воутером Болстерли и Талем Эйнатом в bpo-30977)Улучшена производительность
operator.itemgetter()
на 33%. Оптимизирована обработка аргументов и добавлен быстрый путь для обычного случая использования одного неотрицательного целого индекса в кортеже (что является типичным случаем использования в стандартной библиотеке). (Материал подготовлен Раймондом Хеттингером в bpo-35664.)Ускоренный поиск по полям в
collections.namedtuple()
. Теперь они более чем в два раза быстрее, что делает их самой быстрой формой поиска по переменным экземпляра в Python. (Авторы: Рэймонд Хеттингер, Пабло Галиндо и Джо Жевник, Сергей Сторчака в bpo-32492.)Конструктор
list
не перераспределяет внутренний буфер элементов, если входная итерируемая строка имеет известную длину (вход реализует__len__
). В результате созданный список становится в среднем на 12% меньше. (Материалы предоставлены Раймондом Хеттингером и Пабло Галиндо в bpo-33234.)Удвоена скорость записи в переменную класса. При обновлении атрибута, отличного от dunder, возникал ненужный вызов для обновления слотов. (Материалы предоставлены Стефаном Бенелем, Пабло Галиндо Сальгадо, Раймондом Хеттингером, Нилом Шеменауэром и Сергеем Сторчакой в bpo-36012.)
Уменьшены затраты на преобразование аргументов, передаваемых многим встроенным функциям и методам. Это ускорило вызов некоторых простых встроенных функций и методов на 20-50%. (Предоставлено Сергеем Сторчакой в bpo-23867, bpo-35582 и bpo-36127.)
LOAD_GLOBAL
в инструкции теперь используется новый механизм «кэширования для каждого кода операции». Теперь это примерно на 40% быстрее. (Авторы Юрий Селиванов и Инада Наоки в bpo-26219).
Изменения в сборке и C API¶
Значение по умолчанию
sys.abiflags
стало пустой строкой: флагm
для pymalloc стал бесполезным (сборки с pymalloc и без него совместимы с ABI) и поэтому был удален. (Автор: Виктор Стиннер в 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
должен быть переносимый общедоступный стабильный C API.Include/cpython/*.h
должен быть нестабильный C API, специфичный для CPython; общедоступный API с некоторым частным API с префиксом_Py
или_PY
.Include/internal/*.h
это частный внутренний C API, очень специфичный для CPython. Этот API не имеет гарантии обратной совместимости и не должен использоваться за пределами CPython. Он доступен только для очень специфических нужд, таких как отладчики и профилировщики, которым требуется доступ к внутренним компонентам CPython без вызова функций. Этот API теперь установленmake install
.
(Вклад Виктора Стиннера в bpo-35134 и bpo-35081, работа, начатая Эриком Сноу в Python 3.7.)
Некоторые макросы были преобразованы в статические встроенные функции: типы параметров и возвращаемый тип четко определены, у них нет проблем, характерных для макросов, переменные имеют локальную область действия. Примеры:
PyObject_INIT()
,PyObject_INIT_VAR()
Частные функции:
_PyObject_GC_TRACK()
,_PyObject_GC_UNTRACK()
,_Py_Dealloc()
(Автор: Виктор Стиннер в bpo-35059.)
Функции
PyByteArray_Init()
иPyByteArray_Fini()
были удалены. Они ничего не делали со времен Python 2.7.4 и Python 3.2.0, были исключены из ограниченного API (stable API) и не были задокументированы. (Автор: Виктор Стиннер в bpo-35713.)Результат
PyExceptionClass_Name()
теперь имеет типconst char *
, а неchar *
. (Добавлено Сергеем Сторчакой в bpo-33818.)Двойственность
Modules/Setup.dist
иModules/Setup
была устранена. Ранее при обновлении дерева исходных текстов CPython приходилось вручную копироватьModules/Setup.dist
(внутри дерева исходных текстов) вModules/Setup
(внутри дерева сборки), чтобы отразить любые изменения в вышестоящем потоке. Это принесло небольшую пользу упаковщикам за счет частого раздражения разработчиков после разработки на CPython, поскольку забывание скопировать файл могло привести к сбоям сборки.Теперь система сборки всегда выполняет чтение из
Modules/Setup
в дереве исходного кода. Пользователям, которые хотят настроить этот файл, рекомендуется сохранять свои изменения в git-форке CPython или в виде файлов исправлений, как они делали бы для любых других изменений в дереве исходного кода.(Автор: Антуан Питру в статье bpo-32430.)
Функции, преобразующие число Python в целое число C, такие как
PyLong_AsLong()
, и функции анализа аргументов, такие какPyArg_ParseTuple()
, с преобразованием единиц формата целых чисел, таких как'i'
, теперь будут использовать специальный метод__index__()
вместо__int__()
, если таковые имеются. Предупреждение об устаревании будет выдаваться для объектов с методом__int__()
, но без метода__index__()
(например,Decimal
иFraction
).PyNumber_Check()
теперь будет возвращать1
для объектов, реализующих__index__()
.PyNumber_Long()
,PyNumber_Float()
иPyFloat_AsDouble()
также теперь используйте метод__index__()
, если он доступен. (Автор - Сергей Сторчака в bpo-36048 и bpo-20092.)Объекты типа, размещенные в куче, теперь будут увеличивать количество ссылок в
PyObject_Init()
(и его параллельном макросеPyObject_INIT
) вместоPyType_GenericAlloc()
. Возможно, потребуется скорректировать типы, которые изменяют распределение или отмену доступа к экземплярам. (Автор Эдди Элизондо в bpo-35810).Новая функция
PyCode_NewWithPosOnlyArgs()
позволяет создавать объекты кода, подобныеPyCode_New()
, но с дополнительным параметром posonlyargcount для указания количества позиционных аргументов. (Автор: Пабло Галиндо в статье bpo-37221.)Py_SetPath()
теперь присваиваетsys.executable
полный путь к программе (Py_GetProgramFullPath()
), а не имя программы (Py_GetProgramName()
). (Автор: Виктор Стиннер в статье bpo-38234.)
Осуждаемый¶
Команда distutils
bdist_wininst
теперь устарела, вместо нее используйтеbdist_wheel
(пакеты колес). (Добавлено Виктором Стиннером в bpo-37481.)Устаревшие методы
getchildren()
иgetiterator()
в модулеElementTree
теперь выдаютDeprecationWarning
вместоPendingDeprecationWarning
. Они будут удалены в Python 3.9. (Добавлено Сергеем Сторчакой в bpo-29209.)Передача объекта, который не является экземпляром
concurrent.futures.ThreadPoolExecutor
, вloop.set_default_executor()
устарела и будет запрещена в Python 3.9. (Добавлено Элвисом Пранскявичусом в bpo-34075.)Методы
__getitem__()
изxml.dom.pulldom.DOMEventStream
,wsgiref.util.FileWrapper
иfileinput.FileInput
признаны устаревшими.Реализации этих методов игнорировали их параметр index и возвращали вместо него следующий элемент. (Добавлено Беркером Пексагом в bpo-9372.)
Класс
typing.NamedTuple
отменил использование атрибута_field_types
в пользу атрибута__annotations__
, который содержит ту же информацию. (Добавлено Раймондом Хеттингером в bpo-36320.)ast
классыNum
,Str
,Bytes
,NameConstant
иEllipsis
считаются устаревшими и будут удалены в будущих версиях Python. вместо этого следует использоватьConstant
. (Добавлено Сергеем Сторчакой в bpo-32892.)методы
ast.NodeVisitor
visit_Num()
,visit_Str()
,visit_Bytes()
,visit_NameConstant()
иvisit_Ellipsis()
в настоящее время устарели и не будут вызываться в будущих версиях Python. Добавьте методvisit_Constant()
для обработки всех постоянных узлов. (Добавлено Сергеем Сторчакой в bpo-36917.)Параметр
asyncio.coroutine()
decorator устарел и будет удален в версии 3.10. Вместо@asyncio.coroutine
используйтеasync def
. (Автор: Андрей Светлов в статье 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. (Добавлено Юрием Селивановым в bpo-34790.)Следующие функции и методы являются устаревшими в модуле
gettext
:lgettext()
,ldgettext()
,lngettext()
иldngettext()
. Они возвращают закодированные байты, и возможно, что вы получите неожиданные исключения, связанные с Unicode, если возникнут проблемы с кодировкой переведенных строк. Гораздо лучше использовать альтернативы, которые возвращают строки Unicode в Python 3. Эти функции уже давно не работают.Функция
bind_textdomain_codeset()
, методыoutput_charset()
иset_output_charset()
, а также параметр codeset функцийtranslation()
иinstall()
также являются устаревшими, поскольку они используются только дляl*gettext()
функций. (Автор - Сергей Сторчака в bpo-33710.)Метод
isAlive()
изthreading.Thread
признан устаревшим. (Добавлено Донхи На в bpo-35283.)Многие встроенные и расширенные функции, принимающие целочисленные аргументы, теперь будут выдавать предупреждение об устаревании для
Decimal
s,Fraction
s и любых других объектов, которые могут быть преобразованы в целые числа только с потерями (например, которые имеют__int__()
метод, но у вас нет метода__index__()
). В будущей версии это будут ошибки. (Добавлено Сергеем Сторчакой в bpo-36048.)Рекомендуется передавать следующие аргументы в качестве аргументов ключевых слов:
функция в
functools.partialmethod()
,weakref.finalize()
,profile.Profile.runcall()
,cProfile.Profile.runcall()
,bdb.Bdb.runcall()
,trace.Trace.runfunc()
иcurses.wrapper()
.функция в
unittest.TestCase.addCleanup()
.fn в
submit()
методеconcurrent.futures.ThreadPoolExecutor
иconcurrent.futures.ProcessPoolExecutor
.обратный вызов в
contextlib.ExitStack.callback()
,contextlib.AsyncExitStack.callback()
иcontextlib.AsyncExitStack.push_async_callback()
.c и typeid в
create()
методеmultiprocessing.managers.Server
иmultiprocessing.managers.SharedMemoryServer
.obj в
weakref.finalize()
.
В будущих версиях Python они будут positional-only. (Добавлено Сергеем Сторчакой в bpo-36492.)
Удаление API и функций¶
Следующие функции и API-интерфейсы были удалены из Python 3.8:
Начиная с Python 3.3, импорт азбуки из
collections
устарел, и импорт должен выполняться изcollections.abc
. Возможность импорта из коллекций была помечена для удаления в версии 3.8, но была отложена до версии 3.9. (см. bpo-36952.)Модуль
macpath
, считавшийся устаревшим в Python 3.7, был удален. (Автор: Виктор Стиннер в bpo-35471.)Функция
platform.popen()
была удалена после того, как была признана устаревшей начиная с версии Python 3.3: вместо нее используйтеos.popen()
. (Автор: Виктор Стиннер в bpo-35345.)Функция
time.clock()
была удалена после того, как стала устаревшей начиная с версии Python 3.3: используйте вместо нееtime.perf_counter()
илиtime.process_time()
, в зависимости от ваших требований, для обеспечения четко определенного поведения. (Автор - Маттиас Буссонье в bpo-36895.)Скрипт
pyvenv
был удален в пользуpython3.8 -m venv
, чтобы избежать путаницы в отношении того, к какому интерпретатору Python привязан скриптpyvenv
. (Автор Бретт Кэннон в 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. (Добавлено Сергеем Сторчакой в bpo-29209.)Удален метод
doctype()
изXMLParser
. (Добавлено Сергеем Сторчакой в bpo-29209.)кодек «unicode_internal» удален. (Добавлено Инадой Наоки в bpo-36297.)
Объекты
Cache
иStatement
модуляsqlite3
недоступны для пользователя. (Добавлено Авивом Паливодой в bpo-30262.)Аргумент ключевого слова
bufsize
изfileinput.input()
иfileinput.FileInput()
, который игнорировался и стал устаревшим с момента выхода Python 3.6, был удален. bpo-36952 (автор - Маттиас Буссонье).Функции
sys.set_coroutine_wrapper()
иsys.get_coroutine_wrapper()
, которые считались устаревшими в Python 3.7, были удалены; bpo-36933 (автор - Маттиас Буссонье).
Перенос на Python 3.8¶
В этом разделе перечислены ранее описанные изменения и другие исправления ошибок, которые могут потребовать внесения изменений в ваш код.
Изменения в поведении Python¶
Выражения Yield (как
yield
, так иyield from
) теперь запрещены в понятиях и генераторных выражениях (кроме повторяемого выражения в крайнем левом предложенииfor
). (Автор - Сергей Сторчака в bpo-10544.)Компилятор теперь выдает
SyntaxWarning
, когда проверки подлинности (is
иis not
) используются с определенными типами литералов (например, строками, числами). В CPython это часто может сработать случайно, но не гарантируется спецификацией языка. В предупреждении рекомендуется вместо этого использовать тесты на равенство (==
и!=
). (Автор - Сергей Сторчака в bpo-34850.)Интерпретатор Python может пропускать исключения в некоторых случаях. В версии Python 3.8 это происходит в меньшем количестве случаев. В частности, исключения, возникающие при получении атрибута из словаря типов, больше не игнорируются. (Добавлено Сергеем Сторчакой в bpo-35459.)
Удалены
__str__
реализации из встроенных типовbool
,int
,float
,complex
и несколько классов из стандартной библиотеки. Теперь они наследуют__str__()
отobject
. В результате определение метода__repr__()
в подклассе этих классов повлияет на их строковое представление. (Автор: Сергей Сторчака в bpo-36793.)В AIX
sys.platform
больше не содержит основной версии. Это всегда'aix'
, вместо'aix3'
..'aix7'
. Поскольку более старые версии Python содержат номер версии, рекомендуется всегда использоватьsys.platform.startswith('aix')
. (Добавлено М. Фелтом в bpo-36588.)PyEval_AcquireLock()
иPyEval_AcquireThread()
теперь завершают текущий поток, если вызываются во время завершения работы интерпретатора, что приводит их в соответствие сPyEval_RestoreThread()
,Py_END_ALLOW_THREADS()
иPyGILState_Ensure()
. Если такое поведение нежелательно, защитите вызов, установив флажок_Py_IsFinalizing()
илиsys.is_finalizing()
. (Добавлено Джоанной Нанджекай в bpo-36475.)
Изменения в Python API¶
Функция
os.getcwdb()
теперь использует кодировку UTF-8 в Windows, а не кодовую страницу ANSI: смотрите объяснение в PEP 529. Эта функция больше не является устаревшей в Windows. (Автор: Виктор Стиннер в bpo-37412.)subprocess.Popen
теперь в некоторых случаях для повышения производительности можно использоватьos.posix_spawn()
. В подсистеме Windows для Linux и пользовательской эмуляции QEMU конструкторPopen
, использующийos.posix_spawn()
, больше не вызывает исключения при таких ошибках, как «отсутствует программа». Вместо этого дочерний процесс завершается ошибкой с ненулевым значениемreturncode
. (Материалы предоставлены Джоанной Нанджекай и Виктором Стиннером в bpo-35537.)Аргумент preexec_fn в *
subprocess.Popen
больше не совместим с вспомогательными интерпретаторами. Использование параметра в подинтерпретаторе теперь вызываетRuntimeError
. (Добавлено Эриком Сноу в bpo-34651, изменено Кристианом Хеймсом в bpo-37951.)Метод
imap.IMAP4.logout()
больше не игнорирует произвольные исключения. (Добавлено Виктором Стиннером в bpo-36348.)Функция
platform.popen()
была удалена после того, как была признана устаревшей начиная с версии Python 3.3: вместо нее используйтеos.popen()
. (Автор: Виктор Стиннер в bpo-35345.)Функция
statistics.mode()
больше не генерирует исключение при вводе мультимодальных данных. Вместо этого она возвращает первый режим, который встречается во входных данных. (Добавлено Раймондом Хеттингером в bpo-35892.)Метод
selection()
классаtkinter.ttk.Treeview
больше не принимает аргументы. Его использование с аргументами для изменения выделения было признано устаревшим в Python 3.6. Для изменения выделения используйте специализированные методы, такие какselection_set()
. (Автор - Сергей Сторчака в bpo-31508.)Методы
writexml()
,toxml()
иtoprettyxml()
изxml.dom.minidom
, а также методwrite()
изxml.etree
теперь сохраняют порядок атрибутов, указанный пользователем . (Материалы предоставлены Диего Рохасом и Раймондом Хеттингером в bpo-34160.)База данных
dbm.dumb
, открытая с флагами'r'
, теперь доступна только для чтения.dbm.dumb.open()
с флагами'r'
и'w'
больше не создает базу данных, если она не существует. (Автор - Сергей Сторчака в bpo-32749.)Метод
doctype()
, определенный в подклассеXMLParser
, больше не будет вызываться и будет выдаватьRuntimeWarning
вместоDeprecationWarning
. Определите методdoctype()
для целевого объекта для обработки объявления типа документа XML. (Добавлено Сергеем Сторчакой в bpo-29209.)Значение
RuntimeError
теперь возникает, когда пользовательский метакласс не предоставляет запись__classcell__
в пространстве имен, переданном вtype.__new__
. В Python 3.6-3.7 был созданDeprecationWarning
. (Добавлено Сергеем Сторчакой в bpo-23722.)Класс
cProfile.Profile
теперь можно использовать в качестве контекстного менеджера. (Добавлено Скоттом Сандерсоном в bpo-29235.)shutil.copyfile()
,shutil.copy()
,shutil.copy2()
,shutil.copytree()
иshutil.move()
использовать системные вызовы «быстрого копирования» для конкретной платформы (см. раздел Эффективные операции копирования, зависящие от платформы).shutil.copyfile()
размер буфера по умолчанию в Windows был изменен с 16 КБАЙТ до 1 Мб.Структура
PyGC_Head
полностью изменилась. Весь код, который касался элемента структуры, должен быть переписан. (см. bpo-33597.)Структура
PyInterpreterState
была перенесена во «внутренние» заголовочные файлы (в частности, в/internal/pycore_pystate.h). НепрозрачныйPyInterpreterState
по-прежнему доступен как часть общедоступного API (и стабильного ABI). В документации указано, что ни одно из полей struct не является общедоступным, поэтому мы надеемся, что никто ими не пользовался. Однако, если вы полагаетесь на одно или несколько из этих закрытых полей и у вас нет альтернативы, пожалуйста, откройте проблему с BPO. Мы постараемся помочь вам с настройкой (возможно, включая добавление функций доступа к общедоступному API). (см. bpo-35886).Метод
mmap.flush()
теперь возвращаетNone
при успешном выполнении и генерирует исключение при ошибке на всех платформах. Ранее его поведение зависело от платформы: при успешном выполнении возвращалось ненулевое значение, при ошибке в Windows - ноль. В случае успешного завершения было возвращено нулевое значение; при ошибке в Unix было вызвано исключение. (Добавлено Беркером Пексагом в bpo-2122.)Модули
xml.dom.minidom
иxml.sax
по умолчанию больше не обрабатывают внешние объекты. (Добавлено Кристианом Хеймсом в bpo-17239.)При удалении ключа из базы данных, доступной только для чтения
dbm
(dbm.dumb
,dbm.gnu
илиdbm.ndbm
), возникаетerror
(dbm.dumb.error
,dbm.gnu.error
илиdbm.ndbm.error
) вместоKeyError
. (Автор: Сян Чжан в bpo-33106.)Упрощенный AST для литералов. Все константы будут представлены в виде экземпляров
ast.Constant
. Создание экземпляров старых классовNum
,Str
,Bytes
,NameConstant
иEllipsis
вернет экземплярConstant
. (Автор - Сергей Сторчака в bpo-32892.)expanduser()
в Windows теперь используется переменная окруженияUSERPROFILE
и не используетсяHOME
, которая обычно не устанавливается для обычных учетных записей пользователей. (Автор Энтони Соттайл в bpo-36264.)Исключение
asyncio.CancelledError
теперь наследуется отBaseException
, а не отException
и больше не наследуется отconcurrent.futures.CancelledError
. (Добавлено Юрием Селивановым в bpo-32528.)Функция
asyncio.wait_for()
теперь корректно ожидает отмены при использовании экземпляраasyncio.Task
. Ранее, по достижении таймаута, она отменялась и немедленно возвращалась. (Автор - Элвис Пранскявичус в bpo-32751.)Функция
asyncio.BaseTransport.get_extra_info()
теперь возвращает безопасный для использования объект socket, когда в параметр name передается „socket“. (Добавлено Юрием Селивановым в bpo-37027.)asyncio.BufferedProtocol
перешел на стабильный API.
Зависимости DLL для модулей расширения и библиотек DLL, загруженных с помощью
ctypes
в Windows, теперь разрешены более надежно. Во время загрузки выполняется поиск зависимостей только по системным путям, каталогу, содержащему DLL-файл или PYD-файл, и каталогам, добавленным с помощьюadd_dll_directory()
. В частности,PATH
и текущий рабочий каталог больше не используются, и внесенные в них изменения больше не будут влиять на нормальное разрешение библиотек DLL. Если ваше приложение использует эти механизмы, вам следует проверить наличиеadd_dll_directory()
и, если оно существует, использовать его для добавления каталога ваших библиотек DLL при загрузке вашей библиотеки. Обратите внимание, что пользователям Windows 7 необходимо убедиться в том, что установлено обновление Windows KB2533623 (это также проверяется программой установки). (Автор: Стив Дауэр в bpo-36085).Заголовочные файлы и функции, связанные с gene, были удалены после их замены на реализацию на чистом Python. (Автор Пабло Галиндо в bpo-36623).
types.CodeType
содержит новый параметр во второй позиции конструктора (posonlyargcount) для поддержки только позиционных аргументов, определенных в PEP 570. Первый аргумент (argcount) теперь представляет общее количество позиционных аргументов (включая только позиционные аргументы). Новый методreplace()
изtypes.CodeType
может быть использован для повышения надежности кода в будущем.Параметр
digestmod
дляhmac.new()
по умолчанию больше не использует дайджест MD5.
Изменения в C API¶
Структура
PyCompilerFlags
получила новое поле cf_feature_version. Оно должно быть инициализировано значениемPY_MINOR_VERSION
. По умолчанию это поле игнорируется и используется тогда и только тогда, когда в cf_flags установлен флагPyCF_ONLY_AST
. (Добавлено Гвидо ван Россумом в bpo-35766.)Функция
PyEval_ReInitThreads()
была удалена из C API. Ее не следует вызывать явно: вместо этого используйтеPyOS_AfterFork_Child()
. (Автор: Виктор Стиннер в bpo-36728.)В Unix расширения C больше не связаны с libpython, за исключением Android и Cygwin. Когда Python встроен,
libpython
должен загружаться не с помощьюRTLD_LOCAL
, а с помощьюRTLD_GLOBAL
. Ранее, используяRTLD_LOCAL
, уже было невозможно загрузить расширения C, которые не были связаны сlibpython
, например, расширения C стандартной библиотеки, созданные в разделе*shared*
разделаModules/Setup
. (Автор: Виктор Стиннер в bpo-21536.)Использование
#
вариантов форматов при синтаксическом анализе или построении значения (напримерPyArg_ParseTuple()
,Py_BuildValue()
,PyObject_CallFunction()
и т.д.) безPY_SSIZE_T_CLEAN
определено, что сейчас повышаетсяDeprecationWarning
. Он будет удален в версии 3.10 или 4.0. Подробнее читайте в статье Анализ аргументов и построение значений. (Добавлено Инадой Наоки в статье bpo-36381.)Экземпляры типов, выделенных в куче (например, созданные с помощью
PyType_FromSpec()
), содержат ссылку на свой тип object. Увеличение количества ссылок на объекты этого типа было перенесено сPyType_GenericAlloc()
на функции более низкого уровня:c:func:PyObject_Init иPyObject_INIT()
. Это приводит к тому, что типы, созданные с помощьюPyType_FromSpec()
, ведут себя как другие классы в управляемом коде.Statically allocated types не затрагиваются.
В подавляющем большинстве случаев побочных эффектов быть не должно. Однако типы, которые вручную увеличивают количество ссылок после выделения экземпляра (возможно, для устранения ошибки), теперь могут стать бессмертными. Чтобы избежать этого, эти классы должны вызывать Py_DECREF для объекта типа во время освобождения экземпляра.
Чтобы правильно перенести эти типы в версию 3.8, пожалуйста, внесите следующие изменения:
Удалите
Py_INCREF
для объекта type после выделения экземпляра - если таковой имеется. Это может произойти после вызоваPyObject_New
,PyObject_NewVar
,PyObject_GC_New()
,PyObject_GC_NewVar()
или любого другого пользовательского распределителя, который используетPyObject_Init()
или : c:func: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; }
Убедитесь, что все пользовательские
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);
(Автор: Закери Спитц в bpo-33407.)
Интерпретатор больше не претендует на поддержку бинарной совместимости типов расширений в различных версиях функциональных возможностей. A : c:type:PyTypeObject, экспортированный сторонним модулем расширения, должен содержать все слоты, ожидаемые в текущей версии Python, включая
tp_finalize
(Py_TPFLAGS_HAVE_FINALIZE
больше не проверяется перед чтениемtp_finalize
).(Автор: Антуан Питру в статье bpo-32388.)
Функции
PyNode_AddChild()
иPyParser_AddToken()
теперь принимают два дополнительных аргументаint
end_lineno и end_col_offset.Файл
libpython38.a
, позволяющий инструментам MinGW напрямую связываться сpython38.dll
, больше не входит в обычный дистрибутив Windows. Если вам нужен этот файл, он может быть создан с помощью инструментовgendef
иdlltool
, которые являются частью пакета MinGW binutils:gendef - python38.dll > tmp.def dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a
Расположение установленного
pythonXY.dll
будет зависеть от параметров установки, а также от версии и языка Windows. Дополнительную информацию смотрите в разделе Использование Python в Windows. Результирующая библиотека должна быть помещена в тот же каталог, что иpythonXY.lib
, который обычно является каталогомlibs
при установке Python.(Автор: Стив Дауэр в статье 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
.(Авторы: Марк Шеннон, Антуан Питру и Сергей Сторчака в bpo-17611.)
Добавлен новый код операции
END_ASYNC_FOR
для обработки исключений, возникающих при ожидании следующего элемента в циклеasync for
. (Добавлено Сергеем Сторчакой в bpo-33041.)MAP_ADD
теперь ожидает, что значение будет первым элементом в стеке, а ключ - вторым элементом. Это изменение было внесено таким образом, чтобы ключ всегда вычислялся перед значением при чтении по словарю, как предложено в PEP 572. (Добавлено Йорном Хайслером в bpo-35224.)
Демонстрации и инструменты¶
Добавлен тестовый скрипт для определения времени различных способов доступа к переменным: Tools/scripts/var_access_benchmark.py
. (Добавлено Раймондом Хеттингером в 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, на котором были запущены 64-разрядные сборки macOS, найденные по адресу python.org. Тестовый скрипт отображает время в наносекундах.
Заметные изменения в Python 3.8.1¶
Из-за серьезных проблем с безопасностью параметр reuse_address в asyncio.loop.create_datagram_endpoint()
больше не поддерживается. Это связано с поведением параметра сокета SO_REUSEADDR
в протоколе UDP. Более подробную информацию смотрите в документации для loop.create_datagram_endpoint()
. (Авторы: Кайл Стэнли, Антуан Питру и Юрий Селиванов в bpo-37228.)
Заметные изменения в Python 3.8.2¶
Исправлена регрессия с обратным вызовом ignore
из shutil.copytree()
. Теперь типами аргументов снова являются str и List[str]. (Добавлено Мануэлем Бархау и Джампаоло Родолой в gh-83571.)
Заметные изменения в Python 3.8.3¶
Постоянные значения будущих флагов в модуле __future__
обновлены, чтобы предотвратить столкновение с флагами компилятора. Ранее PyCF_ALLOW_TOP_LEVEL_AWAIT
конфликтовал с CO_FUTURE_DIVISION
. (Автор: Батухан Таскайя в gh-83743)
Заметные изменения в Python 3.8.8¶
Более ранние версии Python позволяли использовать как ;
, так и &
в качестве разделителей параметров запроса в urllib.parse.parse_qs()
и urllib.parse.parse_qsl()
. Из соображений безопасности и в соответствии с новыми рекомендациями W3C это было изменено, чтобы разрешить использование только одного разделительного ключа с &
по умолчанию. Это изменение также затрагивает cgi.parse()
и cgi.parse_multipart()
, поскольку они используют затронутые функции внутри системы. Для получения более подробной информации, пожалуйста, ознакомьтесь с соответствующей документацией. (Материалы предоставлены Адамом Гольдшмидтом, Сентилом Кумараном и Кеном Джином в bpo-42967.)
Заметные изменения в Python 3.8.9¶
Исправление безопасности изменяет поведение ftplib.FTP
, чтобы не доверять IPv4-адресу, отправляемому с удаленного сервера, при настройке пассивного канала передачи данных. Вместо этого мы используем IP-адрес ftp-сервера. Для необычного кода, требующего старого поведения, установите для атрибута trust_server_pasv_ipv4_address
в вашем экземпляре FTP значение True
. (Смотрите gh-87451)
Заметные изменения в Python 3.8.10¶
Поддержка macOS 11.0 (Big Sur) и Apple Silicon Mac¶
Начиная с версии 3.8.10, Python теперь поддерживает сборку и запуск на macOS 11 (Big Sur) и Apple Silicon Mac (на основе архитектуры ARM64
). Теперь доступен новый универсальный вариант сборки, universal2
, который изначально поддерживает как ARM64
, так и Intel 64
в одном наборе исполняемых файлов. Обратите внимание, что поддержка «слабых ссылок», то есть создания двоичных файлов, предназначенных для более новых версий macOS, которые также будут корректно работать в более старых версиях благодаря тестированию во время выполнения на наличие отсутствующих функций, не включена в этот бэкпорт из Python 3.9; чтобы поддерживать различные версии macOS, продолжайте ориентироваться на самую старую версию в линейке и основываться на ней.
((Первоначально материал был подготовлен Рональдом Оуссореном и Лоуренсом Д’Анной в gh-85272, с исправлениями от FX Coudert и Eli Rykoff, а затем перенесен в версию 3.8 Максимом Беланже и Недом Дейли)
Заметные изменения в Python 3.8.10¶
urllib.синтаксический анализ¶
Наличие символов новой строки или табуляции в некоторых частях URL-адреса допускает некоторые формы атак. В соответствии со спецификацией WHATWG, которая обновляет RFC 3986, символы новой строки ASCII \n
, \r
и табуляции \t
удаляются из URL-адреса синтаксическим анализатором в urllib.parse
для предотвращения подобных атак. Удаляемые символы управляются новой переменной уровня модуля urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE
. (Смотрите bpo-43882)
Заметные изменения в Python 3.8.12¶
Изменения в Python API¶
Начиная с версии Python 3.8.12, модуль ipaddress
больше не принимает начальные нули в строках адресов IPv4. Начальные нули неоднозначны и интерпретируются некоторыми библиотеками как восьмеричная запись. Например, устаревшая функция socket.inet_aton()
обрабатывает начальные нули как восьмеричную запись. реализация glibc в современной inet_pton()
не принимает никаких начальных нулей.
(Первоначально добавлено Кристианом Хеймсом в bpo-36384, а затем перенесено в версию 3.8 Ахрафом Мерзуки.)
Примечательная функция безопасности в версии 3.8.14¶
Преобразование между int
и str
в основаниях, отличных от 2 (двоичных), 4, 8 (восьмеричных), 16 (шестнадцатеричных) или 32, таких как основание 10 (десятичных), теперь приводит к появлению ValueError
, если число количество цифр в виде строки превышает допустимый предел, чтобы избежать потенциальных атак типа «отказ в обслуживании» из-за сложности алгоритма. Это ограничение для CVE-2020-10735. Это ограничение можно настроить или отключить с помощью переменной среды, флага командной строки или sys
API. Смотрите документацию по integer string conversion length limitation. Ограничение по умолчанию составляет 4300 цифр в виде строки.
Заметные изменения в версии 3.8.17¶
архивный файл¶
Методы извлечения в
tarfile
иshutil.unpack_archive()
имеют новый аргумент a filter, который позволяет ограничить возможности tar, которые могут быть неожиданными или опасными, например, создание файлов за пределами каталога назначения. Подробнее смотрите в Экстракционные фильтры. В Python 3.12 при использовании без аргумента filter будет отображатьсяDeprecationWarning
. В Python 3.14 значение по умолчанию будет изменено на'data'
. (Автор: Петр Викторин в PEP 706.)