在 Python 中,yield from lock in DatagramProtocol.datagram_received 使得该函数从未被调用
In Python, yielding from lock in DatagramProtocol.datagram_received makes the function never called
我想在协同程序之间同步数据,但我最终得到了一个方法,只要其中有 "yield" 就不会被调用。
更准确地说,当我根据文档 (inspired from this) 使用方法 datagram_received 实现 DatagramProtocol class 时,一切正常,我收到了数据。只要我在方法 datagram_received 中添加 "yield",就再也不会调用该方法。这是一个例子:
loop = asyncio.get_event_loop()
lock = asyncio.Lock(loop=loop)
class MyProtocol(asyncio.DatagramProtocol):
def datagram_received(self, data, addr):
global my_data, lock
print("here")
# uncomment the following lines and datagram_received is
# not called at all (never see the "here" on the console)
#yield from lock
#try:
# my_data = float(data.decode())
#finally:
# lock.release()
loop.run_until_complete(loop.create_datagram_endpoint(MyProtocol, sock=create_socket(10000)))
loop.run_forever()
一个方法怎么会突然不被调用取决于方法的内容?
我错过了什么?应该如何同步?
我错过了什么?
启发您的文档还指出:
Coroutines can be scheduled in a protocol method using ensure_future(), but there is no guarantee made about the execution order. Protocols are not aware of coroutines created in protocol methods and so will not wait for them.
To have a reliable execution order, use stream objects in a coroutine with yield from. For example, the StreamWriter.drain() coroutine can be used to wait until the write buffer is flushed.
您不能在 datagram_received
内 yield from
/await
,您可以:
class MyProtocol(asyncio.DatagramProtocol):
def datagram_received(self, data, addr):
global my_data, lock
print("here")
loop.ensure_future(some_function())
@asyncio.coroutine
def some_function(self):
yield from lock
try:
my_data = float(data.decode())
finally:
lock.release()
一个方法怎么会突然不被调用取决于方法的内容?
在函数中使用 yield
或 yield from
使其成为生成器。所以 datagram_received
returns 生成器对象。要实际执行代码(直到 yield),您应该使用 next
,asyncio 使用(基于生成器的)协程执行它(但同样 datagram_received
不是一个)
>>> def test():
... print('test')
... yield from 'A'
...
>>> test()
<generator object test at 0x7f4165d42fc0>
>>> next(test())
test
'A'
关于生成器的更多信息:https://jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/
我想在协同程序之间同步数据,但我最终得到了一个方法,只要其中有 "yield" 就不会被调用。
更准确地说,当我根据文档 (inspired from this) 使用方法 datagram_received 实现 DatagramProtocol class 时,一切正常,我收到了数据。只要我在方法 datagram_received 中添加 "yield",就再也不会调用该方法。这是一个例子:
loop = asyncio.get_event_loop()
lock = asyncio.Lock(loop=loop)
class MyProtocol(asyncio.DatagramProtocol):
def datagram_received(self, data, addr):
global my_data, lock
print("here")
# uncomment the following lines and datagram_received is
# not called at all (never see the "here" on the console)
#yield from lock
#try:
# my_data = float(data.decode())
#finally:
# lock.release()
loop.run_until_complete(loop.create_datagram_endpoint(MyProtocol, sock=create_socket(10000)))
loop.run_forever()
一个方法怎么会突然不被调用取决于方法的内容?
我错过了什么?应该如何同步?
我错过了什么?
启发您的文档还指出:
Coroutines can be scheduled in a protocol method using ensure_future(), but there is no guarantee made about the execution order. Protocols are not aware of coroutines created in protocol methods and so will not wait for them.
To have a reliable execution order, use stream objects in a coroutine with yield from. For example, the StreamWriter.drain() coroutine can be used to wait until the write buffer is flushed.
您不能在 datagram_received
内 yield from
/await
,您可以:
class MyProtocol(asyncio.DatagramProtocol):
def datagram_received(self, data, addr):
global my_data, lock
print("here")
loop.ensure_future(some_function())
@asyncio.coroutine
def some_function(self):
yield from lock
try:
my_data = float(data.decode())
finally:
lock.release()
一个方法怎么会突然不被调用取决于方法的内容?
在函数中使用 yield
或 yield from
使其成为生成器。所以 datagram_received
returns 生成器对象。要实际执行代码(直到 yield),您应该使用 next
,asyncio 使用(基于生成器的)协程执行它(但同样 datagram_received
不是一个)
>>> def test():
... print('test')
... yield from 'A'
...
>>> test()
<generator object test at 0x7f4165d42fc0>
>>> next(test())
test
'A'
关于生成器的更多信息:https://jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/