CodeGym /Các khóa học /Python SELF VI /Async Context Manager

Async Context Manager

Python SELF VI
Mức độ , Bài học
Có sẵn

9.1 Context Manager

Bạn nhớ cách chúng ta dùng từ khóa with để điều khiển quyền truy cập vào tài nguyên không? Nhờ nó mà có thể theo dõi chính xác, khi nào tài nguyên bắt đầu được sử dụng và khi nào quá trình này kết thúc. Điều tương tự cũng có thể làm với "tài nguyên bất đồng bộ".

Async Context Manager được sử dụng để quản lý tài nguyên trong lập trình bất đồng bộ, đảm bảo mở và đóng tài nguyên đúng cách trong các hàm async. Chúng hoạt động tương tự như các context manager thông thường, nhưng dành cho việc sử dụng trong các hàm async với từ khóa async with.

Mình sẽ không đi sâu phân tích cái này, vì trong thời gian gần, bạn chắc chắn không tạo ra Async Context Manager của riêng mình đâu, và đến lúc bạn quyết định làm điều này, thì có khi bạn cũng quên hết rồi. Nhưng mình muốn giới thiệu cho bạn về khái niệm này.

Tạo Async Context Manager

Async Context Manager được định nghĩa bằng cách sử dụng các phương thức __aenter____aexit__. Các phương thức này tương tự như các phương thức __enter____exit__ trong context manager thông thường, nhưng là bất đồng bộ.

  • __aenter__(): Phương thức async, được gọi khi vào context.
  • __aexit__(exc_type, exc, tb): Phương thức async, được gọi khi thoát context. Nhận ba tham số: loại ngoại lệ, chính ngoại lệ và traceback.

Ví dụ tạo Async Context Manager


import asyncio

class AsyncContextManager:
    async def __aenter__(self):
        print("Vào context")
        return self
        
    async def __aexit__(self, exc_type, exc, tb):
        print("Thoát context")
        
async def main():
    async with AsyncContextManager():
        print("Bên trong context")
        
asyncio.run(main())

Đây là cách mà mã trên sẽ được thực thi:

  1. Hàm async main() chạy
  2. Hàm main() bắt đầu thực hiện
  3. Tạo đối tượng kiểu AsyncContextManager
  4. Phương thức __aenter__() của đối tượng AsyncContextManager được gọi
  5. Xuất ra print("Vào context")
  6. Thực thi mã print("Bên trong context")
  7. Phương thức __aexit__() của đối tượng AsyncContextManager được gọi
  8. Hàm main() kết thúc

9.2 Ví dụ sử dụng

Trong ví dụ trên, không nhất thiết phải sử dụng phiên bản async của context manager — mã vẫn chạy, ngay cả khi bạn làm cho nó đồng bộ.

Nhưng bạn cần async manager khi bên trong block with gọi hàm async hoặc sử dụng từ khóa await.

Async Context Manager cho thao tác với file

Ví dụ này sử dụng thư viện aiofiles để đọc và ghi file bất đồng bộ. Async Context Manager aiofiles.open cho phép mở và đóng file một cách an toàn trong context bất đồng bộ.


import aiofiles
import asyncio
            
async def main():
    async with aiofiles.open('example.txt', mode='w') as file:
        await file.write('Chào, thế giới!')
            
asyncio.run(main())

Async Context Manager cho các hoạt động mạng

Ví dụ này sử dụng thư viện aiohttp để thực hiện các HTTP request bất đồng bộ. Async Context Manager ClientSessionsession.get đảm bảo quản lý kết nối đúng cách.


import aiohttp
import asyncio
            
async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()
            
async def main():
    html = await fetch('https://example.com')
    print(html)
            
asyncio.run(main())

Async Context Manager đảm bảo quản lý tài nguyên tự động, chẳng hạn như file, kết nối mạng và các tài nguyên khác cần phải mở và đóng.

Các phương thức __aenter____aexit__ cho phép thực hiện các thao tác async khi vào và ra khỏi context, đảm bảo thực thi tác vụ song song. Sử dụng Async Context Manager giúp tránh rò rỉ tài nguyên và đảm bảo tất cả các tài nguyên được giải phóng đúng cách.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION