以下宏可以在使用函数时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)
)
该宏通过函数名“/a”检测异步函数。最好 asyncio.iscoroutinefunction
用于检测异步函数。但这不起作用。请查看以下宏和执行结果。
(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'>]
您会看到异步函数被视为 hy-lang 宏中的符号。应用eval
无法避免这个问题。
如何解决这个问题?