我正在寫使用龍捲風網絡的tornado.httpclient.AsyncHTTPClient
使這給我的代碼的async
接口請求庫:可選同步接口異步函數
async def my_library_function():
return await ...
我想使這個接口,如果可選串口用戶提供一個kwarg - 如:serial=True
。雖然你不能明確地調用async
關鍵字中定義的函數,但不需要使用await
。這將是理想的 - 但幾乎可以肯定IMPOSIBLE的語言在此刻:
async def here_we_go():
result = await my_library_function()
result = my_library_function(serial=True)
我沒能在網上找到的任何東西,其中某人想出了一個很好的解決這個。我不想在沒有awaits
的情況下重新實現基本相同的代碼。
這是可以解決的問題,還是需要語言支持?
解決方案(雖然使用傑西的,而不是 - 解釋如下)
下面傑西的解決方案几乎是什麼,我會去用。我最終通過使用裝飾器來獲得我最初想要的界面。事情是這樣的:
import asyncio
from functools import wraps
def serializable(f):
@wraps(f)
def wrapper(*args, asynchronous=False, **kwargs):
if asynchronous:
return f(*args, **kwargs)
else:
# Get pythons current execution thread and use that
loop = asyncio.get_event_loop()
return loop.run_until_complete(f(*args, **kwargs))
return wrapper
這給了你這個接口:
result = await my_library_function(asynchronous=True)
result = my_library_function(asynchronous=False)
我的理智檢查這條巨蟒的異步郵寄名單上,我很幸運,有圭多回應,他禮貌地拍下來這個原因:
代碼異味 - 能夠異步調用相同的功能 和同步是非常令人驚訝的。它也違反了 的規則,即參數的值不應該影響返回類型。
很高興知道這是可能的,但如果不被認爲是一個偉大的接口。 Guido基本上提出了Jesse的回答,並將包裝函數作爲庫中的輔助函數使用,而不是將其隱藏在裝飾器中。
也許寫的代碼作爲發電機基於corou然後使用[types.coroutine()](https://www.python.org/dev/peps/pep-0492/#types-coroutine)創建異步等效項? –