How do you handle asynchronous operations in Python, and when would you choose asyncio over multi-threading?