Tôi có một số mã mã đơn giản được tạo bằng asyncio của Python 3.4 bằng cách sử dụng call_later
. Mã nên in, chờ 10 giây, và sau đó in lại (nhưng thay vì tăng TypeError
khi end()
nên excecuted, xem dưới đây):call_later của asyncio làm tăng đối tượng 'máy phát' không thể gọi với đối tượng coroutine
import asyncio
@asyncio.coroutine
def begin():
print("Starting to wait.")
asyncio.get_event_loop().call_later(10, end())
@asyncio.coroutine
def end():
print("completed")
if __name__ == "__main__":
try:
loop = asyncio.get_event_loop()
loop.create_task(begin())
loop.run_forever()
except KeyboardInterrupt:
print("Goodbye!")
Cung cấp cho các lỗi:
Exception in callback <generator object coro at 0x7fc88eeaddc8>()
handle: <TimerHandle when=31677.188005054 <generator object coro at 0x7fc88eeaddc8>()>
Traceback (most recent call last):
File "/usr/lib64/python3.4/asyncio/events.py", line 119, in _run
self._callback(*self._args)
TypeError: 'generator' object is not callable
Từ những gì tôi có thể kể từ các tài liệu (https://docs.python.org/3/library/asyncio-task.html#coroutine), call_later
lấy một đối tượng coroutine, thu được bằng cách gọi hàm coroutine. Điều này dường như là những gì tôi đã làm, nhưng asyncio không gọi end()
đúng cách.
Việc này phải được thực hiện như thế nào?
Trong trường hợp đó, là có một cách để sắp xếp một coroutine được gọi sau với 'asyncio'? Hay có lý do nào đó tại sao điều này không có ý nghĩa để làm? –
@NathanaelFarley Vâng, bạn có thể sử dụng 'call_later (10, lambda: asyncio.ensure_future (end()))'. Nhưng nó có lẽ có ý nghĩa hơn khi chỉ cần đặt một 'yield từ asyncio.sleep (10)' bên trong 'begin', và sau đó gọi 'yield from end()' ngay sau đó. Nếu bạn không muốn chặn 'bắt đầu', bạn có thể chỉ cần đặt' asyncio.sleep' và gọi đến 'end' trong một coroutine khác, và chỉ cần gọi' asyncio.ensure_future (other_coroutine()) 'bên trong' begin' để thay thế . – dano