Context Managers Python
Context Managers adalah fitur Python yang sangat elegan untuk mengelola resource. Mereka memastikan resource (seperti file, koneksi network, atau database) dibuka dan ditutup dengan benar, bahkan jika terjadi error di tengah proses.
Pernahkah Anda lupa menutup file setelah membukanya? Di Python, hal ini bisa dihindari dengan mudah menggunakan keyword with.
1. Keyword with
Cara paling umum menggunakan Context Manager adalah dengan statement with.
Tanpa Context Manager (Risiko Leak!):
file = open("data.txt", "w")
try:
file.write("Halo Dunia")
finally:
file.close() # Kita harus manual menutupnya
Dengan Context Manager (Aman & Bersih):
with open("data.txt", "w") as file:
file.write("Halo Dunia")
# File otomatis tertutup di sini, bahkan jika ada error saat penulisan.
2. Membuat Context Manager Sendiri
Anda dapat membuat Context Manager sendiri dengan membuat class yang memiliki metode __enter__ dan __exit__.
__enter__: Dijalankan saat memasuki blok with. Nilai return-nya diberikan ke variabel as ....
__exit__: Dijalankan saat keluar dari blok with (selesai normal atau error).
Contoh: Pengelola Koneksi Database (Simulasi)
class KelolaDB:
def __init__(self, nama_db):
self.nama_db = nama_db
def __enter__(self):
print(f"--> Membuka koneksi ke {self.nama_db}")
return self # Objek ini akan menjadi variabel 'db'
def query(self, sql):
print(f"Menjalankan query: {sql}")
def __exit__(self, exc_type, exc_value, traceback):
print(f"<-- Menutup koneksi ke {self.nama_db}")
# Jika ada error, exc_type tidak None
if exc_type:
print(f"Error terjadi: {exc_value}")
# Return True jika ingin menekan error (supaya program tidak crash)
# Return False (default) jika ingin error tetap naik (raise)
# Penggunaan
with KelolaDB("users_db") as db:
db.query("SELECT * FROM users")
# Output:
# --> Membuka koneksi ke users_db
# Menjalankan query: SELECT * FROM users
# <-- Menutup koneksi ke users_db
3. Menggunakan contextlib
Python menyediakan modul contextlib yang memudahkan pembuatan context manager menggunakan generator dan decorator @contextmanager. Ini lebih ringkas daripada membuat class.
from contextlib import contextmanager
@contextmanager
def buka_file_saya(nama):
try:
print("Membuka file...")
f = open(nama, "w")
yield f
finally:
print("Menutup file...")
f.close()
# Penggunaan
with buka_file_saya("test.txt") as f:
f.write("Tes 123")
Kode sebelum yield adalah __enter__, dan kode di blok finally adalah __exit__.
4. Contoh Praktis: Mengukur Waktu Eksekusi
Kita bisa membuat context manager untuk mengukur berapa lama sebuah blok kode berjalan.
import time
from contextlib import contextmanager
@contextmanager
def timer():
start = time.time()
yield
end = time.time()
print(f"Waktu eksekusi: {end - start:.4f} detik")
with timer():
# Simulasi proses berat
time.sleep(1)
x = sum(range(1000000))
# Output: Waktu eksekusi: 1.0xxx detik
Kesimpulan
- Gunakan
withsebisa mungkin saat bekerja dengan file atau koneksi. - Implementasikan
__enter__dan__exit__untuk membuat resource management sendiri. - Gunakan
@contextmanageruntuk cara yang lebih fungsional dan ringkas.