Context Managers — Python

Context Managers & with Context manager adalah objek yang menjamin setup dan cleanup berjalan dengan benar — bahkan saat terjadi error. Kamu pasti sudah pernah

Context Managers & with

Context manager adalah objek yang menjamin setup dan cleanup berjalan dengan benar — bahkan saat terjadi error. Kamu pasti sudah pernah pakai saat membuka file:

with open("data.txt", "r") as f:
    isi = f.read()
# File otomatis ditutup di sini — bahkan jika terjadi error di dalam blok

Kenapa with Dibutuhkan?

Tanpa with, kita harus manual pakai try/finally:

f = open("data.txt", "r")
try:
    isi = f.read()
    # kalau error di sini, f.close() di bawah TETAP dipanggil
finally:
    f.close()

with mengotomatisasi pola ini. File (atau resource apa pun) dijamin ditutup, sekalipun blok melempar exception.

Protokol __enter__ dan __exit__

Class apa pun bisa jadi context manager dengan mengimplementasikan dua dunder method ini:

class Timer:
    def __enter__(self):
        import time
        self.start = time.time()
        return self   # nilai ini di-assign ke variabel setelah "as"

    def __exit__(self, exc_type, exc_val, exc_tb):
        import time
        elapsed = time.time() - self.start
        print(f"Selesai dalam {elapsed:.3f} detik")
        # return False (default) = jangan swallow exception

with Timer() as t:
    # kerjakan sesuatu
    total = sum(range(1_000_000))
# Output: Selesai dalam 0.012 detik

Cara Lebih Mudah: @contextmanager

Kalau enggan membuat class, pakai decorator @contextmanager dari contextlib + generator:

from contextlib import contextmanager

@contextmanager
def buka_koneksi(nama):
    print(f"Buka koneksi ke {nama}")
    try:
        yield nama           # "setup selesai, berikan resource ke blok with"
    finally:
        print(f"Tutup koneksi ke {nama}")   # cleanup, selalu jalan

with buka_koneksi("database") as conn:
    print(f"Query {conn}...")
# Buka koneksi ke database
# Query database...
# Tutup koneksi ke database

Nested with

Boleh gabung beberapa context manager dalam satu baris:

with open("input.txt") as src, open("output.txt", "w") as dst:
    dst.write(src.read())
# Kedua file dijamin ditutup

Use Case Umum

Yang akan kamu pelajari