Hầu hết các hướng dẫn đều hiển thị ví dụ tầm thường with open(...) và dừng lại. Đây là ba mẫu mà tôi thực sự sử dụng trong mã thực tế, và chế độ lỗi mà mỗi mẫu ngăn chặn.

Trường hợp 1: Dọn dẹp tài nguyên và xử lý lỗi

Khi bạn có tài nguyên phải dọn dẹp, bất kể điều gì xảy ra:

 1class DatabaseConnection:
 2    def __init__(self, config):
 3        self.config = config
 4        self.connection = None
 5    
 6    def __enter__(self):
 7        self.connection = create_connection(self.config)
 8        return self.connection
 9    
10    def __exit__(self, exc_type, exc_val, exc_tb):
11        if self.connection:
12            self.connection.close()

Tại sao điều này quan trọng

  • Dọn dẹp tài nguyên ngay cả trong trường hợp ngoại lệ
  • Ngăn chặn rò rỉ tài nguyên
  • Làm cho mã đáng tin cậy hơn

Trường hợp 2: Quản lý trạng thái tạm thời

Khi bạn cần thay đổi tạm thời một số trạng thái, sau đó khôi phục nó:

 1class TempDir:
 2    def __init__(self, base_path="/tmp"):
 3        self.base_path = base_path
 4        self.temp_path = None
 5    
 6    def __enter__(self):
 7        import tempfile
 8        self.temp_path = tempfile.mkdtemp(dir=self.base_path)
 9        return self.temp_path
10    
11    def __exit__(self, exc_type, exc_val, exc_tb):
12        import shutil
13        if self.temp_path and os.path.exists(self.temp_path):
14            shutil.rmtree(self.temp_path)

Tại sao điều này quan trọng

  • Tự động dọn dẹp tệp tạm thời
  • Ngăn chặn lãng phí không gian đĩa
  • Đơn giản hóa xử lý lỗi

Trường hợp 3: Giám sát hiệu suất và thời gian

Khi bạn cần đo thời gian thực thi mã:

 1import time
 2
 3class Timer:
 4    def __enter__(self):
 5        self.start = time.time()
 6        return self
 7    
 8    def __exit__(self, exc_type, exc_val, exc_tb):
 9        self.end = time.time()
10        print(f"Thời gian thực thi: {self.end - self.start:.2f} giây")

Tại sao điều này quan trọng

  • Tự động tính thời gian khối mã
  • Báo cáo thời gian ngay cả trong trường hợp ngoại lệ
  • Dễ dàng giám sát hiệu suất

Điểm chính

  1. Context managers không chỉ dành cho tệp - Chúng áp dụng cho bất kỳ tài nguyên nào cần thiết lập/dọn dẹp
  2. An toàn ngoại lệ - Phương thức __exit__ luôn được gọi, ngay cả trong trường hợp ngoại lệ
  3. Có thể kết hợp - Bạn có thể lồng nhiều context managers
  4. Có thể tái sử dụng - Tạo một lần, sử dụng nhiều lần

Ứng dụng thực tế

Những mẫu này rất hữu ích trong mã thực tế, đặc biệt khi xử lý kết nối cơ sở dữ liệu, tệp tạm thời, kết nối mạng hoặc các thao tác cần thời gian chính xác.

Hãy nhớ: Context managers là con dao quân đội Thụy Sĩ cho quản lý tài nguyên trong Python. Học cách sử dụng chúng sẽ làm cho mã của bạn mạnh mẽ và dễ bảo trì hơn.