TL; доктор
Мы можем написать функцию обертки синхронизации функции ASYNC:
import asyncio from functools import wraps, partial def async_wrap(func): @wraps(func) async def run(*args, loop=None, executor=None, **kwargs): if loop is None: loop = asyncio.get_event_loop() pfunc = partial(func, *args, **kwargs) return await loop.run_in_executor(executor, pfunc) return run
Использовать это:
import time import os async_sleep = async_wrap(time.sleep) async_remove = async_wrap(os.remove) # or use decorator style @async_wrap def my_async_sleep(duration): time.sleep(duration)
Дольше описание
Если мы используем синхронные функции Time.sleep
В функции и запустить его 3 раза:
import time def count(): print("func start") time.sleep(1) print("func end") def main(): funcs = [count, count, count] for func in funcs: func() if __name__ == "__main__": start = time.time() main() end = time.time() print(f"Time elapse: {end-start}")
Запустить его:
func start func end func start func end func start func end Time elapse: 3.00303053855896
Общая стоимость времени составляет около 3 секунд.
Теперь давайте будем использовать Async версию Time.sleep
(Мы можем использовать asyncio.sleep
от Python’s Asyncio
Стандартная библиотека, но здесь, чтобы продемонстрировать наше async_wrap
Функция работает, мы собираемся использовать наши собственные async_sleep
Функция).
import asyncio from functools import wraps, partial import time def async_wrap(func): @wraps(func) async def run(*args, loop=None, executor=None, **kwargs): if loop is None: loop = asyncio.get_event_loop() pfunc = partial(func, *args, **kwargs) return await loop.run_in_executor(executor, pfunc) return run async_sleep = async_wrap(time.sleep) async def count(): print("func start") await async_sleep(1) print("func end") async def main(): await asyncio.gather(count(), count(), count()) if __name__ == "__main__": start = time.time() asyncio.run(main()) end = time.time() print(f"Time elapse: {end-start}")
Здесь мы используем asyncio.ghather
запустить Считать
функция три раза. Теперь запустите это:
func start func start func start func end func end func end Time elapse: 1.007828950881958
Мы можем видеть нашу асинхронитую версию только около 1 секунды! И наше async_sleep
Функция работает!
Ссылка:
- https://stackoverflow.com/questions/43241221/how-can-i-wrap-a-synchronous-function-in-an-async-coroutine
- https://github.com/Tinche/aiofiles/blob/master/aiofiles/os.py
- https://github.com/yifeikong/aioify/blob/master/aioify/__init__.py
- https://realpython.com/async-io-python/
Оригинал: “https://dev.to/0xbf/turn-sync-function-to-async-python-tips-58nn”