Що нового в Python 3.8¶
- Редактор:
Raymond Hettinger
У цій статті пояснюється нові функції в Python 3.8 порівняно з 3.7. Python 3.8 було випущено 14 жовтня 2019 року. Щоб отримати повну інформацію, перегляньте журнал змін.
Підсумок – основні моменти випуску¶
Нові можливості¶
Вирази присвоєння¶
Існує новий синтаксис :=
, який призначає значення змінним як частину більшого виразу. Його ласкаво називають «оператором моржа» через його схожість з очима та бивнями моржа <https://en.wikipedia.org/wiki/Walrus#/media/File:Pacific_Walrus_-_Bull_(8247646168).jpg>.
У цьому прикладі вираз присвоєння допомагає уникнути виклику 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.)
Лише позиційні параметри¶
There is a new function parameter syntax /
to indicate that some
function parameters must be specified positionally and cannot be used as
keyword arguments. This is the same notation shown by help()
for C
functions annotated with Larry Hastings“
Argument Clinic tool.
У наступному прикладі параметри 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
Додаткова перевага позначення параметра як лише позиційного полягає в тому, що це дозволяє змінювати ім’я параметра в майбутньому без ризику зламати код клієнта. Наприклад, у модулі statistic
назва параметра 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 для повного опису.
(Надав Pablo Galindo в bpo-36540.)
Паралельний кеш файлової системи для скомпільованих файлів байт-коду¶
Нове налаштування PYTHONPYCACHEPREFIX
(також доступне як -X
pycache_prefix
) налаштовує неявний кеш байт-коду на використання окремого паралельного дерева файлової системи, а не стандартних підкаталогів __pycache__
всередині кожен вихідний каталог.
Розташування кешу повідомляється в sys.pycache_prefix
(None
вказує на розташування за умовчанням у підкаталогах __pycache__
).
(Надано Карлом Майєром у bpo-33499.)
Збірка налагодження використовує той самий ABI, що й збірка випуску¶
Тепер Python використовує той самий ABI, незалежно від того, чи створено його в режимі випуску чи налагодження. У Unix, коли Python створено в режимі налагодження, тепер можна завантажувати розширення C, створені в режимі випуску, і розширення C, створені за допомогою стабільного ABI.
Випускні збірки та налагоджувальні збірки тепер сумісні з 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 створено в режимі налагодження, імпорт тепер також шукає розширення 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 дозволяють краще контролювати відображення результату виразу:
>>> 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 додає Audit Hook і 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 для документації.
Дивіться PEP 587 для повного опису.
(Надав Віктор Стіннер у bpo-36763.)
PEP 590: Vectorcall: швидкий протокол виклику для CPython¶
Протокол Vectorcall додано до API Python/C. Він призначений для формалізації існуючих оптимізацій, які вже були зроблені для різних класів. Будь-який 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 дає змогу написатичисельник, знаменник = x.as_integer_ratio()
і налаштувати його роботу з кількома числовими типами. (Надано Лізою Роуч у bpo-33073 та Реймондом Геттінгером у bpo-37819.)Конструктори
int
,float
іcomplex
тепер використовуватимуть спеціальний метод__index__()
, якщо він доступний, і відповідний метод__int__()
,__float__()
або__complex__()
недоступні. (Надав Сергій Сторчака у bpo-20092.)Added support of
\N{name}
escapes inregular 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.)
Dict і 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
, і відповідний ступінь цієї оберненої величини для інших від’ємних показників степеня. Наприклад, щоб обчислити модульний мультиплікативний обернений 38 за модулем 137, напишіть:>>> pow(38, -1, 137) 119 >>> 119 * 38 % 137 1
Модульні обернені виникають при розв’язуванні «лінійних діофантових рівнянь <https://en.wikipedia.org/wiki/Diophantine_equation>» _. Наприклад, щоб знайти цілочисельні розв’язки для
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 «коментарів типу підпису» (повертається для вузлів AST визначення функції);feature_version=(3, N)
дозволяє вказати попередню версію Python 3. Наприклад,feature_version=(3, 4)
розглядатимеasync
іawait
як незарезервовані слова.
(Надав Гвідо ван Россум у bpo-35766.)
asyncio¶
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()
має бути кращим способом запуску асинхронних програм.
(Надав Юрій Селіванов у 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.)
Асинхронним завданням тепер можна присвоювати назви, передавши аргумент ключового слова name
до asyncio.create_task()
або методу циклу подій create_task()
, або викликавши set_name()
метод об’єкта завдання. Ім’я завдання відображається у виведенні 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
. Це працює, оскільки звичайні dicts мають гарантоване впорядкування, починаючи з Python 3.7. Якщо потрібні додаткові функції OrderedDict
, запропонованим виправленням є приведення результату до потрібного типу: OrderedDict(nt._asdict())
. (Надав Реймонд Геттінгер у bpo-35864.)
cProfile¶
Клас 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.)
ctypes¶
У Windows CDLL
і підкласи тепер приймають параметр winmode для визначення прапорів для основного виклику LoadLibraryEx
. Прапорці за замовчуванням встановлено лише для завантаження залежностей DLL із надійних місць, включаючи шлях, де зберігається DLL (якщо повний або частковий шлях використовується для завантаження початкової DLL), і шляхи, додані add_dll_directory()
. (Надав Стів Дауер у bpo-36085.)
дата, час¶
Added new alternate constructors datetime.date.fromisocalendar()
and
datetime.datetime.fromisocalendar()
, which construct date
and
datetime
objects respectively from ISO year, week number, and weekday;
these are the inverse of each class’s isocalendar
method.
(Contributed by Paul Ganssle in bpo-36004.)
functools¶
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()
, який перетворює методи на загальні функції за допомогою 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.)
gettext¶
Додано pgettext()
та його варіанти. (Надано Францом Гласнером, Еріком Араужо та Шеріл Сабеллою в bpo-2504.)
gzip¶
Додано параметр mtime до gzip.compress()
для відтворюваного виведення. (Надав Guo Ci Teo в bpo-34898.)
Виняток BadGzipFile
тепер викликається замість OSError
для певних типів недійсних або пошкоджених файлів gzip. (Надано Філіпом Грущинським, Мікеле Орру та Закері Шпітцем у bpo-6584.)
IDLE і idlelib¶
Виведення в N рядків (50 за замовчуванням) стиснуто до кнопки. N можна змінити в розділі PyShell на сторінці «Загальні» діалогового вікна «Параметри». Менше, але, можливо, наддовгих рядків можна стиснути, клацнувши правою кнопкою миші на виводі. Стиснутий вихід можна розгорнути на місці, подвійним клацанням кнопки або в буфер обміну чи окреме вікно, клацнувши кнопку правою кнопкою миші. (Надав Тал Ейнат у bpo-1529353.)
Додайте «Run Customized» до меню «Run», щоб запустити модуль із налаштованими налаштуваннями. Будь-які введені аргументи командного рядка додаються до sys.argv. Вони також знову з’являються в полі для наступного налаштованого запуску. Можна також придушити звичайний перезапуск основного модуля Shell. (Надано Шеріл Сабелла, Террі Ян Ріді та іншими в bpo-5680 і bpo-37627.)
Додано додаткові номери рядків для вікон редактора IDLE. Вікна відкриваються без номерів рядків, якщо не встановлено інше на вкладці «Загальні» діалогового вікна налаштування. Номери рядків для існуючого вікна відображаються та ховаються в меню «Параметри». (Надано Тал Ейнат і Саймадхав Геблікар у bpo-17535.)
Власне кодування ОС тепер використовується для перетворення між рядками Python і об’єктами Tcl. Це дозволяє IDLE працювати з емодзі та іншими символами, відмінними від BMP. Ці символи можна відобразити або скопіювати та вставити в буфер обміну або з нього. Перетворення рядків із Tcl на Python і назад тепер ніколи не дає збою. (Багато людей працювали над цим вісім років, але нарешті проблему вирішив Сергій Сторчака в bpo-13153.)
Нове в 3.8.1:
Додайте опцію для вимкнення блимання курсору. (Надав Закері Шпітц у bpo-4603.)
Клавіша Escape тепер закриває вікна завершення IDLE. (Надав Джонні Наджера в 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.)
io¶
У режимі розробки (-X
env
) і в debug build фіналізатор io.IOBase
тепер реєструє виняток, якщо close()
метод не вдається. Виняток ігнорується за умовчанням у збірці випуску. (Надав Віктор Стіннер у bpo-18748.)
itertools¶
Функція itertools.accumulate()
додала опцію initial аргумент ключового слова для визначення початкового значення:
>>> from itertools import accumulate
>>> list(accumulate([10, 5, 30, 15], initial=1000))
[1000, 1010, 1015, 1045, 1060]
(Надано Лізою Роуч у bpo-34659.)
json.tool¶
Додайте опцію --json-lines
, щоб аналізувати кожен рядок введення як окремий об’єкт JSON. (Надано Weipeng Hong у bpo-31553.)
лісозаготівля¶
Додано аргумент ключового слова force до logging.basicConfig()
Якщо встановлено значення true, усі існуючі обробники, приєднані до кореневого реєстратора, видаляються та закриваються перед виконанням конфігурації, визначеної іншими аргументами.
Це вирішує давню проблему. Після виклику реєстратора або basicConfig() наступні виклики basicConfig() мовчки ігнорувалися. Через це було складно оновлювати, експериментувати з різними параметрами конфігурації журналу або навчати їх за допомогою інтерактивної підказки або блокнота Jupyter.
(Suggested by Raymond Hettinger, implemented by Donghee Na, and reviewed by Vinay Sajip in 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
(Надано 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
(Надав Марк Дікінсон у bpo-36887.)
Функція math.factorial()
більше не приймає аргументи, які не є int-подібними. (Надав Пабло Галіндо в bpo-33083.)
mmap¶
Клас mmap.mmap
тепер має метод madvise()
для доступу до системного виклику madvise()
. (Надав Закері Шпітц у bpo-32941.)
багатопроцесорність¶
Додано новий модуль multiprocessing.shared_memory
. (Надав Девін Поттс у bpo-35813.)
У macOS метод запуску spawn тепер використовується за замовчуванням. (Надав Віктор Стіннер у bpo-33725.)
ос¶
Додано нову функцію add_dll_directory()
у Windows для надання додаткових шляхів пошуку для власних залежностей під час імпорту модулів розширення або завантаження DLL за допомогою ctypes
. (Надав Стів Дауер у bpo-36085.)
Було додано нову функцію os.memfd_create()
для обгортання системного виклику memfd_create()
. (Надано 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()
тепер може розглядати перехрестя як посилання.
(Надав Стів Дауер у bpo-37834.)
os.path¶
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¶
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()
, який створює жорстке посилання, що вказує на шлях. (Надано Joannah Nanjekye у bpo-26978)
маринований огірок¶
Розширення pickle
, що створюють субкласи оптимізованого для C Pickler
, тепер можуть перевизначати логіку маринування функцій і класів, визначаючи спеціальний метод reducer_override()
. (Надано П’єром Глейзером і Олів’є Грізелем у bpo-35900.)
plistlib¶
Додано новий plistlib.UID
і ввімкнено підтримку для читання та запису бінарних списків у кодуванні NSKeyedArchiver. (Надав Джон Янзен у bpo-26707.)
pprint¶
Модуль 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()
тепер підтримує тихий режим. (Надано Joannah Nanjekye у bpo-22640.)
шлекс¶
Нова функція shlex.join()
діє як зворотна функція shlex.split()
. (Надав Бо Бейлс у bpo-32102.)
шутил¶
shutil.copytree()
тепер приймає новий аргумент ключового слова dirs_exist_ok
. (Надав Джош Бронсон у bpo-20849.)
shutil.make_archive()
тепер за замовчуванням використовує сучасний формат pax (POSIX.1-2001) для нових архівів для покращення переносимості та відповідності стандартам, успадкованому від відповідних змін у модулі tarfile
. (Надано C.A.M. Gerlach у bpo-30661.)
shutil.rmtree()
у Windows тепер видаляє з’єднання каталогів без попереднього рекурсивного видалення їх вмісту. (Надав Стів Дауер у bpo-37834.)
гніздо¶
Додано зручні функції create_server()
і has_dualstack_ipv6()
для автоматизації необхідних завдань, які зазвичай виконуються під час створення серверного сокета, включаючи прийняття з’єднань 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.unraisablehook()
, яку можна перевизначати, щоб керувати обробкою «виключних ситуацій, які не можна викликати». Він викликається, коли сталася виняткова ситуація, але Python не може її впоратися. Наприклад, коли деструктор викликає виняток або під час збирання сміття (gc.collect()
). (Надав Віктор Стіннер у bpo-36829.)
tarfile¶
Модуль tarfile
тепер за замовчуванням використовує сучасний формат pax (POSIX.1-2001) для нових архівів замість попереднього, специфічного для GNU. Це покращує міжплатформенну переносимість завдяки узгодженому кодуванню (UTF-8) у стандартизованому та розширюваному форматі та пропонує кілька інших переваг. (Надано C.A.M. Gerlach у 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 tokenizer. (Надав Аммар Аскар у bpo-33899.)
tkinter¶
Додано методи selection_from()
, selection_present()
, selection_range()
та selection_to()
у клас tkinter.Spinbox
. (Надано Juliette Monsel у bpo-34829.)
Додано метод moveto()
в клас tkinter.Canvas
. (Надано Джульєтт Монсел у bpo-23831.)
Клас tkinter.PhotoImage
тепер має методи transparency_get()
і transparency_set()
. (Надав Закері Шпітц у bpo-25451.)
час¶
Added new clock CLOCK_UPTIME_RAW
for macOS 10.12.
(Contributed by Joannah Nanjekye in bpo-35702.)
введення тексту¶
Модуль 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()
. Прості азбуки, такі якtyping.SupportsInt
тепер є підкласамиProtocol
.Новий клас протоколу
typing.SupportsIndex
.Нові функції
typing.get_origin()
іtyping.get_args()
.
unicodedata¶
The unicodedata
module has been upgraded to use the Unicode 12.1.0 release.
Нова функція is_normalized()
може бути використана для перевірки того, що рядок знаходиться в певній нормальній формі, часто набагато швидше, ніж шляхом фактичної нормалізації рядка. (Надано Максом Беланджером, Девідом Юресті та Грегом Прайсом у bpo-32285 та bpo-37966).
unittest¶
Додано AsyncMock
для підтримки асинхронної версії Mock
. Також додано відповідні нові функції assert для тестування. (Надано Лізою Роуч у bpo-26467).
Додано addModuleCleanup()
і addClassCleanup()
до unittest для підтримки очищення для setUpModule()
і setUpClass()
. (Надано Лізою Роуч у bpo-24412.)
Кілька імітаційних функцій підтвердження тепер також друкують список фактичних викликів у разі невдачі. (Надано Петтером Страндмарком у 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¶
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 є помилковим;
Параметри preexec_fn, pass_fds, cwd і start_new_session не встановлені;
виконуваний шлях містить каталог.
(Надано Джоанною Нанджекі та Віктором Стіннером у bpo-35537.)
shutil.copyfile()
,shutil.copy()
,shutil.copy2()
,shutil.copytree()
іshutil.move()
використовують спеціальну для платформи «швидку -copy» системні виклики в Linux і macOS для більш ефективного копіювання файлу. «швидке копіювання» означає, що операція копіювання відбувається всередині ядра, уникаючи використання буферів простору користувача в Python, як у «outfd.write(infd.read())
». У Windowsshutil.copyfile()
використовує більший розмір буфера за замовчуванням (1 МіБ замість 16 КіБ) і використовується варіантmemoryview()
на основіshutil.copyfileobj()
. Прискорення копіювання файлу розміром 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()
особливо швидшим у мережевих файлових системах. (Надав Джампаоло Родола в 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__
, щоб зменшити обсяг пам’яті. (Надано Wouter Bolsterlee і Tal Einat у 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
— це приватний внутрішній API C, специфічний для CPython. Цей API не має гарантії зворотної сумісності, тому його не слід використовувати поза CPython. Він доступний лише для дуже специфічних потреб, таких як налагоджувачі та профілі, які мають доступ до внутрішніх елементів CPython без виклику функцій. Цей API тепер встановлено за допомогоюmake install
.
(Надано Віктором Стіннером у bpo-35134 та bpo-35081, робота, розпочата Еріком Сноу над Python 3.7.)
Деякі макроси було перетворено на статичні вбудовані функції: типи параметрів і тип повернення добре визначені, вони не мають проблем, характерних для макросів, змінні мають локальні області видимості. приклади:
PyObject_INIT()
,PyObject_INIT_VAR()
Private functions:
_PyObject_GC_TRACK()
,_PyObject_GC_UNTRACK()
,_Py_Dealloc()
(Надав Віктор Стіннер у bpo-35059.)
The
PyByteArray_Init()
andPyByteArray_Fini()
functions have been removed. They did nothing since Python 2.7.4 and Python 3.2.0, were excluded from the limited API (stable ABI), and were not documented. (Contributed by Victor Stinner in 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()
now setssys.executable
to the program full path (Py_GetProgramFullPath()
) rather than to the program name (Py_GetProgramName()
). (Contributed by Victor Stinner in 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.)The
__getitem__()
methods ofxml.dom.pulldom.DOMEventStream
,wsgiref.util.FileWrapper
andfileinput.FileInput
have been deprecated.Реалізації цих методів ігнорували параметр index і замість нього повертали наступний елемент. (Надано Berker Peksag у 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.)The
isAlive()
method ofthreading.Thread
has been deprecated. (Contributed by Donghee Na in bpo-35283.)Багато вбудованих функцій і функцій розширення, які приймають цілі аргументи, тепер видаватимуть попередження про застаріленість для
Decimal
s,Fraction
s та будь-яких інших об’єктів, які можна перетворити лише на цілі числа із втратою (наприклад, які мають метод__int__()
, але не мають методу__index__()
). У наступній версії вони будуть помилками. (Надав Сергій Сторчака в bpo-36048.)Застаріло передавати такі аргументи як аргументи ключового слова:
func у
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 вони будуть позиційними лише. (Надав Сергій Сторчака в bpo-36492.)
Видалення API та функцій¶
З Python 3.8 видалено наступні функції та API:
Починаючи з 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. Усі інші параметри тепер лише для ключових слів. (Надав Сергій Сторчака в 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.)Інтерпретатор CPython може ковтати винятки за деяких обставин. У Python 3.8 це відбувається в меншій кількості випадків. Зокрема, винятки, викликані під час отримання атрибута зі словника типів, більше не ігноруються. (Надав Сергій Сторчака в bpo-35459.)
Видалено реалізації
__str__
із вбудованих типівbool
,int
,float
,complex
і кількох класів зі стандартної бібліотеки. Тепер вони успадковують__str__()
відobject
. Як наслідок, визначення методу__repr__()
у підкласі цих класів вплине на їхнє представлення рядків. (Надав Сергій Сторчака в bpo-36793.)On AIX,
sys.platform
doesn’t contain the major version anymore. It is always'aix'
, instead of'aix3'
..'aix7'
. Since older Python versions include the version number, so it is recommended to always usesys.platform.startswith('aix')
. (Contributed by M. Felt in bpo-36588.)PyEval_AcquireLock()
andPyEval_AcquireThread()
now terminate the current thread if called while the interpreter is finalizing, making them consistent withPyEval_RestoreThread()
,Py_END_ALLOW_THREADS()
, andPyGILState_Ensure()
. If this behavior is not desired, guard the call by checking_Py_IsFinalizing()
orsys.is_finalizing()
. (Contributed by Joannah Nanjekye in bpo-36475.)
Зміни в API Python¶
Функція
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-декларації doctype. (Надав Сергій Сторчака в bpo-29209.)Помилка
RuntimeError
тепер виникає, коли спеціальний метаклас не надає запис__classcell__
у просторі імен, переданому вtype.__new__
.DeprecationWarning
було видано в Python 3.6–3.7. (Надав Сергій Сторчака в bpo-23722.)Клас
cProfile.Profile
тепер можна використовувати як контекстний менеджер. (Надав Скотт Сандерсон у bpo-29235.)shutil.copyfile()
,shutil.copy()
,shutil.copy2()
,shutil.copytree()
іshutil.move()
використовують спеціальну для платформи «швидку -copy» системні виклики (див. розділ Залежні від платформи ефективні операції копіювання).shutil.copyfile()
розмір буфера за замовчуванням у Windows змінено з 16 KiB на 1 MiB.Структура
PyGC_Head
повністю змінилася. Весь код, який торкався члена структури, слід переписати. (Див. bpo-33597.)Структуру
PyInterpreterState
було переміщено у «внутрішні» файли заголовків (зокрема, Include/internal/pycore_pystate.h). НепрозорийPyInterpreterState
все ще доступний як частина публічного API (і стабільного ABI). У документах зазначено, що жодне з полів структури не є відкритим, тому ми сподіваємось, що ніхто ними не користувався. Однак, якщо ви покладаєтеся на одне або кілька з цих приватних полів і не маєте альтернативи, будь ласка, відкрийте проблему BPO. Ми допоможемо вам налаштувати (можливо, включаючи додавання функцій доступу до публічного API). (Див. bpo-35886.)Метод
mmap.flush()
тепер повертаєNone
у разі успіху та викликає виняток у разі помилки на всіх платформах. Раніше його поведінка залежала від платформи: ненульове значення поверталося в разі успіху; нуль було повернуто через помилку під Windows. У разі успіху було повернуто нульове значення; виняток було викликано помилкою під Unix. (Надано Berker Peksag у 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
. (Надав Xiang Zhang у 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, коли „socket“ передається в параметр name. (Надав Юрій Селіванов у bpo-37027.)asyncio.BufferedProtocol
перейшов на стабільний API.
Залежності DLL для модулів розширення та DLL, завантажених за допомогою
ctypes
у Windows, тепер вирішуються більш безпечно. На наявність залежностей під час завантаження шукаються лише системні шляхи, каталог, що містить файл DLL або PYD, і каталоги, додані за допомогоюadd_dll_directory()
. Зокрема,PATH
і поточний робочий каталог більше не використовуються, і їх зміни більше не впливатимуть на нормальну роздільну здатність DLL. Якщо ваша програма покладається на ці механізми, вам слід перевіритиadd_dll_directory()
і, якщо вона існує, використати її для додавання каталогу DLLs під час завантаження бібліотеки. Зауважте, що користувачам Windows 7 потрібно буде переконатися, що Windows Update KB2533623 інстальовано (це також перевіряє інсталятор). (Надав Стів Дауер у bpo-36085.)Файли заголовків і функції, пов’язані з pgen, були видалені після заміни на чисту реалізацію Python. (Надав Пабло Галіндо в bpo-36623.)
types.CodeType
має новий параметр у другій позиції конструктора (posonlyargcount) для підтримки лише позиційних аргументів, визначених у PEP 570. Перший аргумент (argcount) тепер представляє загальну кількість позиційних аргументів (включаючи лише позиційні аргументи). Новий методreplace()
types.CodeType
можна використовувати, щоб зробити код готовим до майбутнього.Параметр
digestmod
дляhmac.new()
більше не використовує дайджест MD5 за замовчуванням.
Зміни в C API¶
The
PyCompilerFlags
structure got a new cf_feature_version field. It should be initialized toPY_MINOR_VERSION
. The field is ignored by default, and is used if and only ifPyCF_ONLY_AST
flag is set in cf_flags. (Contributed by Guido van Rossum in bpo-35766.)The
PyEval_ReInitThreads()
function has been removed from the C API. It should not be called explicitly: usePyOS_AfterFork_Child()
instead. (Contributed by Victor Stinner in 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()
) містять посилання на свій об’єкт типу. Збільшення кількості посилань на ці типи об’єктів було переміщено зPyType_GenericAlloc()
до функцій більш низького рівня,PyObject_Init()
іPyObject_INIT()
. Це змушує типи, створені черезPyType_FromSpec()
, поводитися як інші класи в керованому коді.Статично виділені типи не впливають.
У переважній більшості випадків побічних ефектів бути не повинно. Однак типи, які вручну збільшують кількість посилань після виділення екземпляра (можливо, щоб обійти помилку), тепер можуть стати безсмертними. Щоб уникнути цього, ці класи повинні викликати Py_DECREF для об’єкта типу під час звільнення примірника.
Щоб правильно перенести ці типи в 3.8, застосуйте такі зміни:
Remove
Py_INCREF
on the type object after allocating an instance - if any. This may happen after callingPyObject_New
,PyObject_NewVar
,PyObject_GC_New()
,PyObject_GC_NewVar()
, or any other custom allocator that usesPyObject_Init()
orPyObject_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.)
The interpreter does not pretend to support binary compatibility of extension types across feature releases, anymore. A
PyTypeObject
exported by a third-party extension module is supposed to have all the slots expected in the current Python version, includingtp_finalize
(Py_TPFLAGS_HAVE_FINALIZE
is not checked anymore before readingtp_finalize
).(Надав Антуан Пітру в bpo-32388.)
The functions
PyNode_AddChild()
andPyParser_AddToken()
now accept two additionalint
arguments end_lineno and 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
The benchmarks were measured on an Intel® Core™ i7-4960HQ processor running the macOS 64-bit builds found at python.org. The benchmark script displays timings in nanoseconds.
Помітні зміни в Python 3.8.1¶
Через серйозні проблеми безпеки параметр reuse_address asyncio.loop.create_datagram_endpoint()
більше не підтримується. Це через поведінку опції сокета SO_REUSEADDR
в UDP. Для отримання додаткової інформації див. документацію для loop.create_datagram_endpoint()
. (Надано Кайлом Стенлі, Антуаном Пітру та Юрієм Селівановим у bpo-37228.)
Notable changes in Python 3.8.2¶
Fixed a regression with the ignore
callback of shutil.copytree()
.
The argument types are now str and List[str] again.
(Contributed by Manuel Barkhau and Giampaolo Rodola in gh-83571.)
Notable changes in Python 3.8.3¶
The constant values of future flags in the __future__
module
are updated in order to prevent collision with compiler flags. Previously
PyCF_ALLOW_TOP_LEVEL_AWAIT
was clashing with CO_FUTURE_DIVISION
.
(Contributed by Batuhan Taskaya in gh-83743)
Помітні зміни в Python 3.8.8¶
Попередні версії Python дозволяли використовувати як ;
, так і &
як роздільники параметрів запиту в urllib.parse.parse_qs()
і urllib.parse.parse_qsl()
. З міркувань безпеки та для відповідності новим рекомендаціям W3C це було змінено, щоб дозволити лише один роздільний ключ із &
за замовчуванням. Ця зміна також впливає на cgi.parse()
і cgi.parse_multipart()
, оскільки вони використовують уражені функції внутрішньо. Щоб дізнатися більше, перегляньте відповідну документацію. (Надано Адамом Ґолдшмідтом, Сентилом Кумараном і Кеном Джином у bpo-42967.)
Notable changes in Python 3.8.9¶
A security fix alters the ftplib.FTP
behavior to not trust the
IPv4 address sent from the remote server when setting up a passive data
channel. We reuse the ftp server IP address instead. For unusual code
requiring the old behavior, set a trust_server_pasv_ipv4_address
attribute on your FTP instance to True
. (See gh-87451)
Notable changes in Python 3.8.10¶
macOS 11.0 (Big Sur) and Apple Silicon Mac support¶
As of 3.8.10, Python now supports building and running on macOS 11
(Big Sur) and on Apple Silicon Macs (based on the ARM64
architecture).
A new universal build variant, universal2
, is now available to natively
support both ARM64
and Intel 64
in one set of executables.
Note that support for «weaklinking», building binaries targeted for newer
versions of macOS that will also run correctly on older versions by
testing at runtime for missing features, is not included in this backport
from Python 3.9; to support a range of macOS versions, continue to target
for and build on the oldest version in the range.
(Originally contributed by Ronald Oussoren and Lawrence D’Anna in gh-85272, with fixes by FX Coudert and Eli Rykoff, and backported to 3.8 by Maxime Bélanger and Ned Deily)
Notable changes in Python 3.8.10¶
urllib.parse¶
The presence of newline or tab characters in parts of a URL allows for some
forms of attacks. Following the WHATWG specification that updates RFC 3986,
ASCII newline \n
, \r
and tab \t
characters are stripped from the
URL by the parser in urllib.parse
preventing such attacks. The removal
characters are controlled by a new module level variable
urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE
. (See bpo-43882)
Помітні зміни в Python 3.8.12¶
Зміни в API Python¶
Починаючи з Python 3.8.12, модуль ipaddress
більше не приймає жодних початкових нулів у рядках адрес IPv4. Початкові нулі є неоднозначними та інтерпретуються деякими бібліотеками як вісімкове позначення. Наприклад, застаріла функція socket.inet_aton()
розглядає початкові нулі як вісімкове позначення. glibc реалізація сучасного inet_pton()
не приймає жодних початкових нулів.
(Спочатку надано Крістіаном Хеймсом у bpo-36384, а також перенесено до 3.8 Ахрафом Мерзукі.)
Notable security feature in 3.8.14¶
Converting between int
and str
in bases other than 2
(binary), 4, 8 (octal), 16 (hexadecimal), or 32 such as base 10 (decimal)
now raises a ValueError
if the number of digits in string form is
above a limit to avoid potential denial of service attacks due to the
algorithmic complexity. This is a mitigation for CVE-2020-10735.
This limit can be configured or disabled by environment variable, command
line flag, or sys
APIs. See the integer string conversion
length limitation documentation. The default limit
is 4300 digits in string form.
Notable changes in 3.8.17¶
tarfile¶
The extraction methods in
tarfile
, andshutil.unpack_archive()
, have a new a filter argument that allows limiting tar features than may be surprising or dangerous, such as creating files outside the destination directory. See Extraction filters for details. In Python 3.12, use without the filter argument will show aDeprecationWarning
. In Python 3.14, the default will switch to'data'
. (Contributed by Petr Viktorin in PEP 706.)