Trình quản lý bối cảnh Python: Tạo tùy chỉnh với các khối

Tìm hiểu cách viết trình quản lý bối cảnh tùy chỉnh bằng Python. Nắm vững trình trang trí trình quản lý bối cảnh và các phương thức __enter__/__exit__ để đảm bảo an toàn tài nguyên.

Thử trong Trình chỉnh sửa

Tổng quan

Trình quản lý bối cảnh là một cơ chế tinh tế trong Python được thiết kế để xử lý việc thiết lập và phân chia các tài nguyên bên ngoài. Trong phần mềm, nhiều thao tác yêu cầu các cặp hành động: mở và đóng tệp, kết nối và ngắt kết nối khỏi cơ sở dữ liệu hoặc lấy và mở khóa. Nếu một chương trình gặp sự cố sau bước thiết lập nhưng trước bước chia nhỏ, các tài nguyên đó vẫn bị khóa trong bộ nhớ. Người quản lý bối cảnh đảm bảo rằng tài nguyên được dọn sạch an toàn trong mọi trường hợp.

Cách tiêu chuẩn để gọi trình quản lý bối cảnh là sử dụng câu lệnh `with`. Tóm lại, bất kỳ đối tượng nào được sử dụng trong câu lệnh `with` đều phải triển khai Giao thức Trình quản lý bối cảnh. Giao thức này bao gồm hai phương thức đặc biệt: `__enter__()` và `__exit__()`. Khi khối `with` bắt đầu, `__enter__()` được gọi để chuẩn bị tài nguyên. Khi khối `with` kết thúc hoặc phát sinh một ngoại lệ, `__exit__()` được tự động kích hoạt, nhận thông tin về bất kỳ ngoại lệ nào được nêu ra để nó có thể xử lý việc dọn dẹp hoặc loại bỏ lỗi.

Đối với các trường hợp sử dụng đơn giản, việc viết một lớp bằng các phương thức `__enter__` và `__exit__` có thể cảm thấy dài dòng. Để đơn giản hóa điều này, thư viện chuẩn của Python cung cấp mô-đun `contextlib`, có tính năng trang trí `@contextmanager`. Trình trang trí này cho phép bạn viết một hàm tạo đơn giản chứa một câu lệnh `yield`. Mã trước `yield` đóng vai trò là thiết lập, giá trị mang lại đóng vai trò là tài nguyên và mã sau `yield` biểu thị việc dọn dẹp. Nắm vững trình quản lý bối cảnh đảm bảo ứng dụng của bạn không bị rò rỉ.

Đầu ra mã & thực thi

Một lớp tùy chỉnh triển khai __enter__ và __exit__ để quản lý ranh giới ghi nhật ký thực thi.

class CustomManager:
    def __enter__(self):
        print("--> Resource Setup: Entering the block")
        return "RESOURCE_KEY"

    def __exit__(self, exc_type, exc_value, traceback):
        print("<-- Resource Teardown: Exiting the block")
        if exc_type:
            print(f"Exception Intercepted: {exc_value}")
        return True  # Suppress exceptions

with CustomManager() as res:
    print(f"Working inside block with resource: {res}")
    # Force an error to verify exception handling
    x = 1 / 0
print("Program continues running safely.")
Đầu ra thiết bị đầu cuối
--> Resource Setup: Entering the block
Working inside block with resource: RESOURCE_KEY
<-- Resource Teardown: Exiting the block
Exception Intercepted: division by zero
Program continues running safely.

Triển khai từng bước

  • Quản lý các giao dịch cơ sở dữ liệu (cam kết thành công, khôi phục khi có lỗi)
  • Thu thập và giải phóng các khóa luồng trong mã đa luồng
  • Chuyển hướng đầu ra tiêu chuẩn (stdout) trong tập lệnh kiểm tra đơn vị

Câu hỏi thường gặp

Làm cách nào để loại bỏ các ngoại lệ trong trình quản lý ngữ cảnh tùy chỉnh?

Bằng cách trả về True từ phương thức __exit__. Nếu nó trả về True, mọi ngoại lệ được đưa ra bên trong khối sẽ bị loại bỏ.

Bạn có thể kết hợp nhiều trình quản lý bối cảnh trong một câu lệnh không?

Có, bạn có thể phân tách chúng bằng dấu phẩy, ví dụ: với open('file1.txt') là f1, open('file2.txt') là f2:.

Chủ đề liên quan

Tài nguyên Python được đề xuất

Mở rộng kiến thức của bạn với các hướng dẫn tương tác, bảng ghi chú và so sánh mã có liên quan.