ite*_*em4 11 python asynchronous python-3.x python-asyncio
我正在开发python聊天机器人框架asyncio.但是我看PEP-492并且有新的语法,async/ await最后它被接受了.
我喜欢async/ awaitsyntax,我想用它.但我担心3.4后缀兼容性.
如果我在代码中使用新语法,有人可以在3.4中使用它吗?
例如,我写了一些这样的代码,
import asyncio
class ChatBot:
def __init__(self, loop):
self.loop = loop
async def connect(self):
self.reader, self.writer = await asyncio.open_connect(HOST, PORT, loop=self.loop)
async def read():
return await self.reader.read()
async def run(self):
running = True
while running:
try:
await self.connect()
line = await self.read()
if not line:
continue
await self.parse(line)
except BotInternalError as e:
if e.stop:
running = False
break
except:
pass
async def parse(self, msg):
if msg.startswith('PING'):
self.pong()
elif msg.startswith('ERROR'):
self.error()
else:
await self.some_work(msg)
async def some_work(self, msg):
# some looooooooong works
self.send(msg)
def send(self, msg):
self.writer.write(msg)
Run Code Online (Sandbox Code Playgroud)
比,我可以在py35中使用它
loop = asyncio.get_event_loop() # I don't know it really needed in py35.
bot = ChatBot(loop)
asyncio.run_until_complete(bot.run())
Run Code Online (Sandbox Code Playgroud)
但是,py34没有await语法.如果我在没有版本限制的PyPI上面上传源代码并且某人在py34上安装了它,它会正常工作吗?我怎么能保留它?
dan*_*ano 13
如果您需要在代码中支持Python 3.4,则需要使用旧的@asyncio.coroutine/ yield fromstyle语法.如果不运行3.5,就无法支持async/ awaitsyntax; 你将获得SyntaxError3.4或更低的编译时间.
这需要的新功能,你的优势唯一可以以向后兼容的方式做的就是各种添加__a*__方法到类在适当情况下(__aiter__,__aenter__,__aexit__等),使用yield from协程语法.这样,您的对象可以支持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)
Run Code Online (Sandbox Code Playgroud)
在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())
Run Code Online (Sandbox Code Playgroud)
在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())
Run Code Online (Sandbox Code Playgroud)
如果你正在编写一个使用的应用程序,这可能没有用asyncio,但是如果你正在开发一个供其他开发人员使用的库或框架,那么它值得做.
| 归档时间: |
|
| 查看次数: |
4545 次 |
| 最近记录: |