kopia lustrzana https://github.com/animator/learn-python
111 wiersze
3.7 KiB
Markdown
111 wiersze
3.7 KiB
Markdown
![]() |
## Asynchronous Context Managers and Generators in Python
|
||
|
Asynchronous programming in Python allows for more efficient use of resources by enabling tasks to run concurrently. Python provides support for asynchronous
|
||
|
context managers and generators, which help manage resources and perform operations asynchronously.
|
||
|
|
||
|
### Asynchronous Context Managers
|
||
|
Asynchronous context managers are similar to regular context managers but are designed to work with asynchronous code. They use the async with statement and
|
||
|
typically include the '__aenter__' and '__aexit__' methods.
|
||
|
|
||
|
### Creating an Asynchronous Context Manager
|
||
|
Here's a simple example of an asynchronous context manager:
|
||
|
|
||
|
```bash
|
||
|
import asyncio
|
||
|
|
||
|
class AsyncContextManager:
|
||
|
async def __aenter__(self):
|
||
|
print("Entering context")
|
||
|
await asyncio.sleep(1) # Simulate an async operation
|
||
|
return self
|
||
|
|
||
|
async def __aexit__(self, exc_type, exc, tb):
|
||
|
print("Exiting context")
|
||
|
await asyncio.sleep(1) # Simulate cleanup
|
||
|
|
||
|
async def main():
|
||
|
async with AsyncContextManager() as acm:
|
||
|
print("Inside context")
|
||
|
|
||
|
asyncio.run(main())
|
||
|
```
|
||
|
|
||
|
Output:
|
||
|
|
||
|
```bash
|
||
|
Entering context
|
||
|
Inside context
|
||
|
Exiting context
|
||
|
```
|
||
|
|
||
|
### Asynchronous Generators
|
||
|
Asynchronous generators allow you to yield values within an asynchronous function. They use the async def syntax along with the yield statement and are
|
||
|
iterated using the async for loop.
|
||
|
|
||
|
### Creating an Asynchronous Generator
|
||
|
Here's a basic example of an asynchronous generator:
|
||
|
|
||
|
```bash
|
||
|
import asyncio
|
||
|
|
||
|
async def async_generator():
|
||
|
for i in range(5):
|
||
|
await asyncio.sleep(1) # Simulate an async operation
|
||
|
yield i
|
||
|
|
||
|
async def main():
|
||
|
async for value in async_generator():
|
||
|
print(value)
|
||
|
|
||
|
asyncio.run(main())
|
||
|
```
|
||
|
Output:
|
||
|
```bash
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
3
|
||
|
4
|
||
|
```
|
||
|
### Combining Asynchronous Context Managers and Generators
|
||
|
You can combine asynchronous context managers and generators to create more complex and efficient asynchronous workflows.
|
||
|
Example: Fetching Data with an Async Context Manager and Generator
|
||
|
Consider a scenario where you need to fetch data from an API asynchronously and manage the connection using an asynchronous context manager:
|
||
|
```bash
|
||
|
import aiohttp
|
||
|
import asyncio
|
||
|
|
||
|
class AsyncHTTPClient:
|
||
|
def __init__(self, url):
|
||
|
self.url = url
|
||
|
|
||
|
async def __aenter__(self):
|
||
|
self.session = aiohttp.ClientSession()
|
||
|
self.response = await self.session.get(self.url)
|
||
|
return self.response
|
||
|
|
||
|
async def __aexit__(self, exc_type, exc, tb):
|
||
|
await self.response.release()
|
||
|
await self.session.close()
|
||
|
|
||
|
async def async_fetch(urls):
|
||
|
for url in urls:
|
||
|
async with AsyncHTTPClient(url) as response:
|
||
|
data = await response.text()
|
||
|
yield data
|
||
|
|
||
|
async def main():
|
||
|
urls = ["http://example.com", "http://example.org", "http://example.net"]
|
||
|
async for data in async_fetch(urls):
|
||
|
print(data)
|
||
|
|
||
|
asyncio.run(main())
|
||
|
```
|
||
|
### Benefits of Asynchronous Context Managers and Generators
|
||
|
1. Efficient Resource Management: They help manage resources like network connections or file handles more efficiently by releasing them as soon as they are no longer needed.
|
||
|
2. Concurrency: They enable concurrent operations, improving performance in I/O-bound tasks such as network requests or file I/O.
|
||
|
3. Readability and Maintainability: They provide a clear and structured way to handle asynchronous operations, making the code easier to read and maintain.
|
||
|
### Summary
|
||
|
Asynchronous context managers and generators are powerful tools in Python that enhance the efficiency and readability
|
||
|
of asynchronous code. By using 'async with' for resource management and 'async for' for iteration, you can write more performant and maintainable asynchronous
|
||
![]() |
programs.
|