Ho un codice semplice fatto con asyncio di Python 3.4 usando call_later
. Il codice dovrebbe stampare, attende 10 secondi, quindi stampare di nuovo (ma invece solleva TypeError
quando end()
dovrebbe essere excecuted, vedi sotto):asyncio's call_later solleva l'oggetto 'generator' non è richiamabile con oggetto 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!")
dà l'errore:
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
Da quello che posso Dagli documenti (https://docs.python.org/3/library/asyncio-task.html#coroutine), call_later
prende un oggetto coroutine, che si ottiene chiamando una funzione di coroutine. Questo sembra essere quello che ho fatto, ma asyncio non chiama correttamente end()
.
Come dovrebbe essere fatto?
In questo caso, c'è un modo per programmare un coroutine da chiamare successivamente con 'asyncio'? O c'è qualche ragione per cui questo non ha senso da fare? –
@NathanaelFarley Bene, puoi usare 'call_later (10, lambda: asyncio.ensure_future (end()))'. Ma probabilmente ha più senso semplicemente mettere un 'yield from asyncio.sleep (10)' dentro 'begin', e poi chiamare' yield from end() 'subito dopo. Se non vuoi bloccare 'begin', puoi semplicemente mettere 'asyncio.sleep' e chiamare a' end' in un'altra coroutine, e chiamare 'asyncio.ensure_future (other_coroutine())' all'interno 'begin' invece . – dano