Zac*_*tes 23 python generator python-3.x python-asyncio yield-from
我有一个Connection
用于包含读取和写入asyncio
连接流的对象:
class Connection(object):
def __init__(self, stream_in, stream_out):
object.__init__(self)
self.__in = stream_in
self.__out = stream_out
def read(self, n_bytes : int = -1):
return self.__in.read(n_bytes)
def write(self, bytes_ : bytes):
self.__out.write(bytes_)
yield from self.__out.drain()
Run Code Online (Sandbox Code Playgroud)
在服务器端,每次客户端连接时connected
创建一个Connection
对象,然后读取4个字节.
@asyncio.coroutine
def new_conection(stream_in, stream_out):
conn = Connection(stream_in, stream_out)
data = yield from conn.read(4)
print(data)
Run Code Online (Sandbox Code Playgroud)
在客户端,写出4个字节.
@asyncio.coroutine
def client(loop):
...
conn = Connection(stream_in, stream_out)
yield from conn.write(b'test')
Run Code Online (Sandbox Code Playgroud)
这个作品几乎为预期的,但我必须yield from
每天read
和write
电话.我yield from
从里面尝试过Connection
:
def read(self, n_bytes : int = -1):
data = yield from self.__in.read(n_bytes)
return data
Run Code Online (Sandbox Code Playgroud)
但不是获取数据,而是获得类似的输出
<generator object StreamReader.read at 0x1109983b8>
Run Code Online (Sandbox Code Playgroud)
如果我打电话read
,并write
从多个地方,我宁愿不要重复yield from
每次秒; 而是把它们放在里面Connection
.我的最终目标是削减我的new_conection
功能:
@asyncio.coroutine
def new_conection(stream_in, stream_out):
conn = Connection(stream_in, stream_out)
print(conn.read(4))
Run Code Online (Sandbox Code Playgroud)
小智 5
因为StreamReader.read
是一个协程,你调用它的唯一选择是a)将它包装在一个Task
or中Future
并通过一个事件循环运行它,b)await
从定义的协程中运行它async def
,或者c)yield from
从一个定义为函数的协程中使用它与@asyncio.coroutine
.
由于Connection.read
从事件循环(通过协程new_connection
)调用,您无法重用该事件循环来运行Task
或Future
for StreamReader.read
:事件循环在它们已经运行时无法启动.您要么必须停止事件循环(灾难性的,可能无法正确执行),要么创建新的事件循环(混乱并且无法使用协同程序).这些都不是可取的,因此Connection.read
需要成为协程或async
函数.
另外两个选项(await
在async def
协程或yield from
在@asyncio.coroutine
-decorated函数)大部分是等价的.唯一的区别是,async def
并且await
在Python 3.5中添加,因此对于3.4,使用yield from
和@asyncio.coroutine
是唯一的选项(协同程序并且asyncio
在3.4之前不存在,因此其他版本无关紧要).就个人而言,我更喜欢使用async def
和await
,因为定义协同程序async def
比装饰器更清晰,更清晰.
简而言之:拥有Connection.read
和new_connection
成为协同程序(使用装饰器或async
关键字),并在调用其他协程(in 和in )时使用await
(或).yield from
await conn.read(4)
new_connection
await self.__in.read(n_bytes)
Connection.read
归档时间: |
|
查看次数: |
1322 次 |
最近记录: |