Soal 1Ketika kamu mendekorasi fungsi generator dengan @contextmanager, mengapa ia perlu yield tepat sekali?
contextlib — Manajemen Resource dan with Kustom
Pelajari @contextmanager plus yield untuk membuat with tanpa class, cleanup pasti via try/finally, dan menelan exception spesifik dengan suppress lewat contoh.
contextlib adalah modul yang harus kamu pakai ketika ingin menulis with statement sendiri. Kita akan membahas dua alat paling sederhananya secara berurutan: @contextmanager untuk cara paling sederhana mendefinisikannya, dan suppress untuk menelan exception tertentu.
@contextmanager — definisikan with statement dengan mudah
with statement Python adalah cara aman untuk menangani "hal-hal yang harus kamu bersihkan setelah dipakai" — open file, koneksi DB, akuisisi lock, dan sebagainya. Untuk membuat class bekerja dengan with dengan tangan, kamu perlu mendefinisikan __enter__ / __exit__, yang merupakan banyak boilerplate. @contextmanager adalah jalan pintas: tulis satu generator (fungsi yang berisi yield) dan kamu mendapatkan context manager yang bekerja dengan with. Kode sebelum yield adalah "awal aksi", dan kode setelahnya adalah "cleanup".
yield adalah yang diikat oleh as di with statement.from contextlib import contextmanager
# --- Referensi: membangun class yang kompatibel dengan with ----------
# class Section:
# def __init__(self, name):
# self.name = name
# def __enter__(self):
# print(f"--- {self.name} start ---")
# return self # value yang diikat oleh `as` with
# def __exit__(self, exc_type, exc, tb):
# print(f"--- {self.name} end ---")
# ----------------------------------------------------------
# Versi @contextmanager: satu fungsi generator melakukan pekerjaan yang sama
@contextmanager
def section(name):
print(f"--- {name} start ---")
yield # tubuh with jalan di sini
print(f"--- {name} end ---")
# Pemakaian
with section("agregasi"):
total = sum(range(100))
print("Total:", total)
# Output:
# --- agregasi start ---
# Total: 4950
# --- agregasi end ---
yield langsung ke setup/teardown — kode jauh lebih sedikit.Pakai try/finally untuk menjamin cleanup bahkan saat exception
Kode setelah yield mungkin tidak jalan jika exception dilempar di dalam blok with. Untuk cleanup yang harus selalu terjadi — menutup file, melepas lock — bungkus tubuh generator dalam try: yield finally: cleanup() untuk keamanan.
suppress — telan exception tertentu
contextlib.suppress(ExceptionType, ...) adalah context manager untuk menelan exception yang ditentukan dan melanjutkan eksekusi. Pola "abaikan saja exception ini dan lanjutkan" — setara dengan try: ... except KeyError: pass — pas dalam satu baris. Kamu bisa mendaftarkan beberapa tipe exception sekaligus, dan apa pun di luar daftar merambat secara normal.
from contextlib import suppress
import os
# "Jalankan dengan nilai default bahkan jika file tidak ada"
config = {"theme": "light", "font_size": 14}
with suppress(FileNotFoundError):
with open("user_config.txt") as f:
config["theme"] = f.read().strip()
# Tidak akan crash jika user_config.txt tidak ada — config tetap pada default
print(config)
# → {'theme': 'light', 'font_size': 14}
# "Lewati diam-diam jika sudah dihapus"
with suppress(FileNotFoundError):
os.remove("old.tmp")
print("Hapus selesai (OK jika tidak ada)")
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Di dalam with suppress(KeyError):, apa yang terjadi ketika KeyError dilempar?