Protokol __enter__ dan __exit__
Buat pengelola konteks menggunakan protokol dunder.
Protokol __enter__ dan __exit__ adalah pelajaran Python Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Python Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Python Academy mencakup 4 pelajaran total.
Protokol Pengelola Konteks
Objek apa pun yang mendefinisikan __enter__ dan __exit__ merupakan pengelola konteks dan dapat digunakan bersama with.
class Managed:
def __enter__(self):
print("entering")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("exiting")
return False
with Managed() as m:
print("inside")Nilai Pengembalian __enter__
__enter__ dipanggil pada awal blok with. Nilai yang dikembalikannya terikat pada variabel setelah as.
class Resource:
def __enter__(self):
self.value = 42
return self # bound to 'r'
def __exit__(self, *args):
self.value = None
return False
with Resource() as r:
print(r.value) # 42Argumen __exit__
__exit__(exc_type, exc_val, exc_tb) menerima informasi pengecualian jika terjadi kesalahan. Jika tidak ada pengecualian, ketiganya bernilai None.
class Safe:
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is ValueError:
print(f"Suppressed ValueError: {exc_val}")
return True # suppress the exception
return False # re-raise anything else
with Safe():
raise ValueError("oops") # suppressedMenyembunyikan Pengecualian
Kembalikan True dari __exit__ untuk menyembunyikan pengecualian. Kembalikan False (atau tidak mengembalikan apa pun) agar pengecualian diteruskan.
class Ignore:
def __enter__(self): return self
def __exit__(self, *args): return True # swallow all exceptions
with Ignore():
1 / 0
print("continues here")Contoh Koneksi Basis Data
Kasus penggunaan klasik: dapatkan koneksi saat masuk, lakukan commit/rollback dan tutup koneksi saat keluar.
class DBConn:
def __enter__(self):
self.conn = connect_db()
return self.conn
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type:
self.conn.rollback()
else:
self.conn.commit()
self.conn.close()
return FalsePengelola Konteks Timer
Ukur waktu yang berlalu dengan mencatat waktu mulai di __enter__ dan menghitung selisihnya di __exit__.
import time
class Timer:
def __enter__(self):
self.start = time.perf_counter()
return self
def __exit__(self, *args):
self.elapsed = time.perf_counter() - self.start
print(f"Elapsed: {self.elapsed:.3f}s")
return False
with Timer():
sum(range(1_000_000))Menyusun Pengelola Konteks
Beberapa pengelola konteks dapat digabungkan dalam satu baris with.
with open("in.txt") as src, open("out.txt", "w") as dst:
dst.write(src.read())Pengelola yang Dapat Digunakan Ulang vs Sekali Pakai
Pengelola konteks yang __enter__-nya mengalokasikan sumber daya baru setiap kali dipanggil dapat digunakan ulang. Pengelola yang menghabiskan keadaan internal (seperti kunci yang hanya dapat ditahan sekali) mungkin tidak dapat digunakan ulang.
class Reusable:
def __enter__(self):
return []
def __exit__(self, *a):
return False
for _ in range(3):
with Reusable() as lst:
lst.append(1)
print(lst) # [1] each time__aenter__ dan __aexit__ (Asinkron)
Untuk pengelola konteks asinkron, definisikan coroutine __aenter__ dan __aexit__, lalu gunakan async with.
class AsyncDB:
async def __aenter__(self):
self.conn = await connect()
return self.conn
async def __aexit__(self, *args):
await self.conn.close()
# async with AsyncDB() as conn:
# ...Membungkus Objek Berkas
Objek berkas Python sudah mengimplementasikan protokol pengelola konteks—jangan pernah memanggil f.close() secara manual.
with open("data.txt", "r") as f:
data = f.read()
# file is closed here automatically
print(f.closed) # TrueMengimplementasikan Lock
Kunci utas adalah pengelola konteks: __enter__ memperoleh kunci, sedangkan __exit__ melepaskannya.
import threading
lock = threading.Lock()
def update_shared():
with lock:
# critical section
passPemeriksaan Singkat
Apa yang harus dikembalikan oleh __exit__ untuk menekan pengecualian?
Ringkasan
Implementasikan __enter__ dan __exit__ untuk membuat pengelola konteks. Kembalikan sumber daya dari __enter__, lalu tangani pembersihan dan penekanan pengecualian di __exit__.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Protokol __enter__ dan __exit__” gratis?
Ya — teks lengkap “Protokol __enter__ dan __exit__” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Python Academy, upgrade ke CoddyKit PRO. Kursus Python Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Protokol __enter__ dan __exit__”?
Buat pengelola konteks menggunakan protokol dunder. Kamu berlatih Python Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Python Academy?
Tidak diperlukan pengalaman sebelumnya. Python Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Protokol __enter__ dan __exit__” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Python Academy ini?
Ya. Setiap pelajaran Python Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Pernyataan with secara Mendalam
- Protokol __enter__ dan __exit__
- contextlib: @contextmanager
- Pola Pengelola Konteks Praktis