![](/img/trans.png)
[英]No matching function for call to 'std::vector<int>::insert' when using a macro
[英]Auto insert await when asyncio function in hy-lang
下面的do/a
宏可以在使用asyncio
函數時自動插入await
。 下面還顯示了用法。
(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'>]
你會看到一個 async 函數在 hy-lang 宏中被視為一個符號。 應用eval
並不能避免這個問題。
如何解決這個問題?
宏在編譯時運行,一個變量是否持有協程只有在運行時才知道,所以需要在運行時調用iscoroutinefunction
。 (asyncio.iscoroutinefunction f)
在您的宏isasynctestmac
僅檢查用作變量名稱的符號,而不是變量的值。 下面是如何使用iscoroutinefunction
編寫do/a
,這里是代碼的其余部分,例如刪除了sleep_test
的額外括號。 (將來,在發布到 Stack Overflow 之前,請確保您的代碼中應該已經可以工作的部分確實已經可以工作。)
(import asyncio time)
(defmacro do/a [&rest code]
`(do ~@(lfor p code
(if (and (instance? HyExpression p) p (!= (first p) (HySymbol "await")))
`(if (asyncio.iscoroutinefunction ~(first p))
(await ~p)
~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)
(print (progn/a
(print 3)
(await (sleep_test/a 3))
(sleep_test/a 2)
(sleep_test 1)
(+ 20 30)))
@Kodiologist 顯示的方法存在以下問題。 以下 python 代碼有效。
import asyncio
import time
async def sleep_testa(t, hintfn):
await asyncio.sleep(t) if asyncio.iscoroutinefunction(hintfn) else time.sleep(t)
但是在def
之前刪除async
后,程序停止並出現錯誤SyntaxError: invalid syntax
import asyncio
import time
def sleep_testa(t, hintfn):
await asyncio.sleep(t) if asyncio.iscoroutinefunction(hintfn) else time.sleep(t)
==> SyntaxError: invalid syntax
動態切換異步和非異步代碼似乎是不可能的。 我們必須在宏展開之前切換異步和非異步代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.