Coroutines are a special type of function in Python that are used for cooperative multitasking. They are similar to generators but can consume and produce values at different times, allowing for more complex workflows.
1. Understanding Coroutines
Coroutines are a type of generator that can pause and resume execution, and they can also accept values through the send()
method. They are typically used for tasks like asynchronous programming and managing stateful computations.
2. Defining a Coroutine
To define a coroutine, use the async def
syntax. Coroutines must be awaited with the await
keyword, and they return awaitable
objects:
import asyncio
async def my_coroutine():
print("Start")
await asyncio.sleep(1)
print("End")
# Run the coroutine
asyncio.run(my_coroutine())
3. Sending Values to Coroutines
Coroutines can accept values using the send()
method. This can be useful for managing state and controlling the flow of execution:
def my_coroutine():
value = yield "Initial"
while True:
received = yield value
value = received + 1
# Create a coroutine object
coro = my_coroutine()
# Initialize the coroutine
print(next(coro)) # Output: Initial
# Send values to the coroutine
print(coro.send(10)) # Output: 10
print(coro.send(20)) # Output: 21
4. Using Coroutines for Asynchronous Programming
Coroutines are particularly useful for asynchronous programming. For example, you can use them to handle I/O operations without blocking the main thread:
import asyncio
async def fetch_data():
print("Fetching data...")
await asyncio.sleep(2)
return "Data fetched"
async def main():
data = await fetch_data()
print(data)
# Run the main coroutine
asyncio.run(main())
5. Practical Example: Coroutines with Asynchronous Tasks
Here’s an example of using coroutines to handle multiple asynchronous tasks concurrently:
import asyncio
async def task(name, delay):
print(f"Task {name} started")
await asyncio.sleep(delay)
print(f"Task {name} completed")
async def main():
# Run multiple tasks concurrently
await asyncio.gather(
task("A", 2),
task("B", 1),
task("C", 3)
)
# Run the main coroutine
asyncio.run(main())
6. Conclusion
Coroutines provide a powerful way to handle asynchronous programming and stateful computations in Python. They allow for more flexible and efficient management of tasks, making them a valuable tool for modern Python development.