Тихо и незаметно (с), Выпущена версия Python 3.5 ! И, конечно же, одно из самых интересных нововведений релиза — новый синтаксис определения сопрограмм с помощью ключевых слов.
асинхронный/ожидание , далее в статье об этом.
Вид поверхности «PEP 0492 — Сопрограммы с синтаксисом async и await» Сначала у меня возник вопрос: «Зачем это нужноЭ» Сопрограммы удовлетворительно реализованы на расширенных генераторах и на первый взгляд может показаться, что все сводится к замене выход из на Ждите и декоратор, создающий сопрограмму на асинхронный .
Сюда же можно добавить ощущение, что все это делалось исключительно для использования с модулем.
асинхронный .
Но это, конечно, не так, тема глубже и интереснее.
сопрограмма
Главное, наверное, то, что теперь сопрограмма в Python — это специальный объект собственная сопрограмма , а не какой-то специально разработанный генератор или что-то еще.Этот объект имеет стандартные библиотечные методы и функции для работы с ним.
То есть теперь это объект, определенный как часть языка.
Ждите
К сожалению, в документации и PEP я не нашел краткого определения того, для чего было введено это новое ключевое слово.Рискну сформулировать это сам: Ключевое слово Ждите указывает, что при выполнении следующего выражения можно переключиться с текущей сопрограммы на другую или на основной поток выполнения.
Соответственно, выражение после Ждите это тоже не просто, это должно быть ожидаемый объект.
ожидаемый объект
Существует три варианта ожидаемых объектов:- Другая сопрограмма, а именно объект собственная сопрограмма .
Этот похож и, видимо, реализован аналогично случаю, когда в генераторе с использованием выход из вызывается другой генератор.
- Сопрограмма на основе генератора, созданная с помощью декоратора типы.
coroutine() .
Это вариант обеспечения совместимости с разработками, где сопрограммы реализованы на основе генераторов.
- Специальный объект, в котором реализован магический метод. __Ждите__ , возвращая итератор.
Используя этот итератор, возвращается результат выполнения сопрограммы.
Ниже этот недостаток будет исправлен.
)
асинхронный
В ПЭП содержится десяток параграфов с заголовками «Почему…» и «Почему бы и нет…».Практически все они посвящены вопросу, почему это ключевое слово используется именно так, а не иначе.
И действительно, асинхронная защита выглядит в коде странно и заставляет задуматься, а не «питонический ли это путь»? С другой стороны, понятно, что им хотелось какой-то более целостной картины, поскольку есть и асинхронный для И асинхронно с .
- асинхронная защита — определяет встроенная функция сопрограммы , результатом которого будет объект сопрограммы собственная сопрограмма , еще не запущен.
- асинхронный для — определяет, что используемый в цикле итератор при получении следующего значения может переключить выполнение с текущей сопрограммы.
Объект-итератор вместо стандартных магических методов имеет: __iter__ И __следующий__ , методы: __aiter__ И __anext__ .
Функционально они схожи, но, как следует из определения, допускают использование await в своем теле.
- асинхронно с — определяет, что при входе и выходе из контекстного блока выполнение может переключаться с текущей сопрограммы.
То же, что и в случае с асинхронным генератором, вместо магических методов: __входить__ И __Выход__ следует использовать функционально аналогичные __aenter__ И __aexit__ .
Мне кажется, «переключение выполнения с текущей сопрограммы» — более правильный вариант. Использование термина «асинхронный код» может ввести в заблуждение, поскольку «асинхронный код» часто реализуется с использованием функций обратного вызова, а это немного другая тема.
Примеров использования асинхронных итераторов и контекстных менеджеров в документации и PEP достаточно, юзекейс в целом понятен и всё логично.
Единственное, что непонятно, — зачем использовать версии магических методов с разными именами, ведь они все равно объявляются с использованием `async def`.
Видимо это что-то связанное с особенностями реализации; Другого объяснения я не вижу.
Как его приготовить?
Изучение какой-то новой функции языка или библиотеки быстро приводит к вопросу о том, как и где ее использовать.А более глубокое исследование, на мой взгляд, следует продолжить на практическом примере.
Для меня, если тема связана с сопрограммами, асинхронностью и тому подобным, то такой практический пример — написание приветственного слова с использованием событийно-ориентированного подхода.
Формулировка задачи следующая: «Вызов функции сна должен остановить выполнение сопрограммы на определенное время».
Сопрограммы и управление событиями хорошо сочетаются друг с другом.
другая моя статья подробнее, почему я так думаю.
И пример такого рода хорошо продемонстрирует нам практически все возможности и нюансы использования сопрограмм.
Допустим, у нас есть диспетчер событий, работающий в основном потоке, который вызывает функции обратного вызова при возникновении ожидаемых событий.
Тогда практическая реализация может быть такой:
- Функция сна настраивает диспетчер событий на вызов функции обратного вызова через указанный период времени.
После этого он передает управление основному потоку выполнения (то есть диспетчеру).
- Функция обратного вызова, переданная диспетчеру, вызывается по истечении указанного времени.
Он переключается на сопрограмму и передает ей полезную информацию.
Как видите, код короткий, вполне понятный и, кстати, рабочий.from time import time from collections import deque from tornado.ioloop import IOLoop current = deque() class sleep(object): def __init__(self, timeout): self.deadline = time() + timeout def __await__(self): def swith_to(coro): current.append(coro) coro.send(time()) IOLoop.instance().
add_timeout(self.deadline, swith_to, current[0]) current.pop() return (yield) def coroutine_start(run, *args, **kwargs): coro = run(*args, **kwargs) current.append(coro) coro.send(None) if __name__ == '__main__': async def hello(name, timeout): while True: now = await sleep(timeout) print("Hello, {}!\tts: {}".
format(name, now)) coroutine_start(hello, "Friends", 1.0) coroutine_start(hello, "World", 2.5) IOLoop.instance().
start()
Опишу в ней основные моменты:
- Используется в качестве диспетчера событий торнадо.
ioloop.IOLoop На мой взгляд комментировать тут особо нечего.
- Сорт спать - реализует ожидаемый объект, его функция — передать управление диспетчеру событий, предварительно настроив его на вызов перезвонить после определенного периода времени.
- Функция обратного вызова определяется как замыкание, но в данном случае это не имеет значения.
Его цель — просто переключить выполнение обратно на сопрограмму, передав текущее время.
Переключение выполнения на сопрограмму осуществляется вызовом ее метода отправлять или метод бросать для переключения с выдачей исключений.
- Функция Назначение coroutine_start — это создать сопрограмму путем вызова фабричной функции и запустить ее на исполнение.
Первый вызов метода отправлять сопрограммы, должны иметь параметр Никто - это запускает сопрограмму
- Сама функция привет тривиально.
Это может быть и понятно, но я думаю, стоит уточнить.
Эта функция не является сопрограммой! Функция, создающая и возвращающая сопрограмму (фабричная функция), аналогична функциям, создающим и возвращающим генератор.
Он еще сырой, но помимо продемонстрированного переключения по событию «таймаут» реализовано переключение сопрограмм по событиям «Ввод-вывод готов» и «системный сигнал».
В качестве демонстрации приведен пример асинхронного эхо-сервера.
Окончательно
Сопрограммы были доступны в том или ином виде уже довольно давно, но «официальных правил игры с ними» не существовало.Теперь эти «правила игры» определены и закреплены, и это станет хорошим поводом для более широкого использования методов асинхронного программирования в Python. В опросе могут участвовать только зарегистрированные пользователи.
Войти , Пожалуйста.
async/await как реализация асинхронного программирования на Python 74,51% Асинхронное программирование на Python необходимо, рассматриваемая реализация приемлема.
576 17,08% Асинхронное программирование на Python необходимо, но рассматриваемая реализация неприемлема.
132 8,41% Асинхронное программирование на Python не требуется 65 Проголосовали 773 пользователя.
462 пользователя воздержались.
Теги: #python 3.5 #async #await #awaitable #asyncio #tornado #coroutine #управляемый событиями #цикл событий #диспетчер событий #python #программирование #проектирование и рефакторинг #Алгоритмы #Параллельное программирование
-
Обзор Продукта На Цифровую Камеру Maxxum D70
19 Oct, 24 -
Шаллер, Джордж Билс
19 Oct, 24 -
Разборка И Приручение Лампового Звука Гитары
19 Oct, 24 -
Робот-Бегун
19 Oct, 24 -
Джанго-Встроенный
19 Oct, 24