Ответ 1
Если вам нужно поддерживать Python 3.4 в коде, вам нужно использовать старый синтаксис стиля @asyncio.coroutine
/yield from
. Невозможно поддерживать синтаксис async
/await
без запуска 3.5; вы получите SyntaxError
во время компиляции 3.4 или ниже.
Единственное, что использует новые функции, которые вы можете сделать с обратной совместимостью, - это добавить различные методы __a*__
к вашим классам (__aiter__
, __aenter__
, __aexit__
и т.д.).), используя синтаксис yield from
coroutine. Таким образом, ваши объекты могут поддерживать операторы async with
/async for
, чтобы пользователи вашей библиотеки, на которой запущен Python 3.5, могли воспользоваться новыми функциями.
Например, этот класс может использоваться с async with
, но не будет прерываться при запуске на Python 3.4:
import asyncio
class Test:
def __enter__(self):
return self
def __exit__(self, *args):
print("arg")
@asyncio.coroutine
def __aenter__(self):
yield from self.init_state()
return self
@asyncio.coroutine
def init_state(self):
yield from asyncio.sleep(2) # Pretend this is real initialization
@asyncio.coroutine
def __aexit__(self, *args):
return self.__exit__(self, *args)
В Python 3.5:
import asyncio
from test import Test
async def main():
print("entering with")
async with Test() as t:
print("in here")
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
В Python 3.4
import asyncio
from test import Test
@asyncio.coroutine
def oldmain():
print("entering with")
with Test() as t:
yield from t.init_state()
print("in here")
loop = asyncio.get_event_loop()
loop.run_until_complete(oldmain())
Это, вероятно, не полезно, если вы пишете приложение, которое использует asyncio
, но если вы разрабатываете библиотеку или структуру, предназначенную для использования другими разработчиками, это стоит того.