Следующий макрос do/a
может автоматически вставлять await
при использовании функции asyncio
. Далее также показано использование.
(import asyncio)
(import time)
(defmacro do/a [&rest code]
`(do ~@(lfor p code
(if
(= (cut (str (first p)) -2) "/a")
`(await ~p)
p))))
(defmacro progn/a [&rest code]
`(.run_until_complete (.get-event-loop asyncio )
((fn/a []
(do/a ~@code)
))
))
(defn/a sleep_test/a [t]
(await (asyncio.sleep t))
(print t)
t)
(defn sleep_test [t]
(time.sleep t)
(print t)
t)
(progn/a
(print 3)
(await (sleep_test/a 3))
(sleep_test/a 2) ;;can omit await
(sleep_test 1) ;;auto swich by fn name
(+ 20 30)
)
Этот макрос обнаруживает асинхронную c функцию по имени функции "/ a". Лучше использовать asyncio.iscoroutinefunction
для обнаружения асинхронных c функций. Но это не работает. Пожалуйста, посмотрите следующий макрос и выполненный результат.
(defmacro isasynctestmac [f]
(if (asyncio.iscoroutinefunction f)
`["async" ~(asyncio.iscoroutinefunction f) (asyncio.iscoroutinefunction ~f) (type ~f)]
`["not async" ~(asyncio.iscoroutinefunction f) (asyncio.iscoroutinefunction ~f) (type ~f)]
))
(isasynctestmac sleep_test/a)
==> ['not async', False, True, <class 'function'>]
Вы увидите, что асиновая c функция рассматривается как символ в макросе hy-lang. Применение eval
не может избежать этой проблемы.
Как решить эту проблему?