Tulip/asyncIO: почему не все вызовы являются асинхронными и указывают, когда вещи должны быть синхронными?

Я отправился на встречу SF Python, когда Guido говорил о Tulip, будущей библиотеке asyncIO для асинхронных операций в Python.

Отказ в том, что если вы хотите, чтобы что-то выполнялось асинхронно, вы можете использовать "yield from" + expression и пару декораторов, чтобы указать, что вызов того, что происходит после yield from, должен выполняться асинхронно. Самое приятное в том, что вы можете нормально читать инструкции в этой функции (как если бы она была синхронной), и она будет вести себя так, как если бы она была синхронной в отношении выполнения этой функции (возвращаемые значения и распространение ошибок и исключений).

Мой вопрос: почему бы не иметь противоположное поведение, а именно, чтобы все вызовы функций были по умолчанию async (и без yield from) и имели различный явный синтаксис, когда вы хотите что-то выполнить синхронно?

(кроме необходимости в другом ключевом слове/синтаксисе)

Ответ 1

Реальный ответ заключается в том, что Guido нравится, что асинхронные точки урока явны в сопрограммах, потому что, если вы не понимаете, что вызов может уступить, тогда приглашение в concurrency проблемы - как с потоками. Но если вам нужно написать явный yield from, достаточно просто убедиться, что он не приземляется в середине двух критических операций, которые должны казаться атомарными для остальной части кода.

Как он упоминает в своей пионерской версии PyCon 2013, существуют другие асинхронные рамки Python, такие как Gevent, которые по умолчанию асинхронны, и он не" Подобный подход. (в 11:58):

И, к сожалению, вы все еще не полностью избавлены от проблемы что планировщик может в случайный момент прервать вашу задачу и переключитесь на другой. [...] Любая функция, которую вы называете сегодня, вы знаете, что он никогда не переключается, завтра кто-то может добавить выражение о регистрации или ленивое кэширование или консультирование настроек файл. [...]

Ответ 2

Обратите внимание, что возможное использование yield from является небольшой частью asynch PEP и никогда не нужно использовать. Возможно, Гидо перепродал их в разговоре; -)

Что касается того, почему функции не изменяются, чтобы всегда быть async по умолчанию, это просто реализм. Асинхронные трюки приносят новые накладные расходы и смысловые сложности, и Python не собирается замедляться и усложнять жизнь для каждого, чтобы сделать несколько приложений легче писать.

Короче говоря, "практичность превосходит чистоту"; -)