Python Academy · Pelajaran

Protokol __enter__ dan __exit__

Bina pengurus konteks menggunakan protokol dunder.

Pelajaran 2 daripada 413 langkah

Protokol __enter__ dan __exit__ ialah pelajaran Python Academy percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Python Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Python Academy merangkumi sejumlah 4 pelajaran.

Protokol Pengurus Konteks

Sebarang objek yang mentakrifkan __enter__ dan __exit__ ialah pengurus konteks dan boleh digunakan dengan 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 Pulangan __enter__

__enter__ dipanggil pada permulaan blok with. Nilai pulangannya diikat kepada pemboleh ubah selepas 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)  # 42

Argumen __exit__

__exit__(exc_type, exc_val, exc_tb) menerima maklumat pengecualian jika ralat berlaku. Jika tiada pengecualian, ketiga-tiganya ialah 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")  # suppressed

Menyembunyikan Pengecualian

Kembalikan True daripada __exit__ untuk menyembunyikan pengecualian. Kembalikan False (atau tiada apa-apa) untuk membenarkannya disebarkan.

class Ignore:
    def __enter__(self): return self
    def __exit__(self, *args): return True  # swallow all exceptions

with Ignore():
    1 / 0

print("continues here")

Contoh Sambungan Pangkalan Data

Kes penggunaan klasik: dapatkan sambungan semasa masuk, lakukan commit/rollback dan tutup sambungan semasa 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 False

Pengurus Konteks Pemasa

Ukur masa berlalu dengan merekodkan permulaan dalam __enter__ dan mengira beza dalam __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))

Pengurus Konteks Bersarang

Berbilang pengurus konteks boleh digabungkan pada satu baris with.

with open("in.txt") as src, open("out.txt", "w") as dst:
    dst.write(src.read())

Pengurus Boleh Guna Semula berbanding Sekali Guna

Pengurus konteks yang __enter__-nya memperuntukkan sumber baharu setiap kali boleh digunakan semula. Pengurus yang menghabiskan keadaan dalaman (seperti kunci yang hanya dipegang sekali) mungkin tidak boleh digunakan semula.

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__ (Tak Segerak)

Untuk pengurus konteks tak segerak, takrifkan korutin __aenter__ dan __aexit__, kemudian 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:
#     ...

Membalut Objek Fail

Objek fail Python sudah melaksanakan protokol pengurus konteks — jangan panggil f.close() secara manual.

with open("data.txt", "r") as f:
    data = f.read()
# file is closed here automatically
print(f.closed)  # True

Melaksanakan Lock

Lock utas ialah pengurus konteks: __enter__ memperoleh lock, manakala __exit__ melepaskannya.

import threading

lock = threading.Lock()

def update_shared():
    with lock:
        # critical section
        pass

Semakan Pantas

Apakah yang perlu dipulangkan oleh __exit__ untuk menyekat pengecualian?

Ulang Kaji

Laksanakan __enter__ dan __exit__ untuk mencipta pengurus konteks. Pulangkan sumber daripada __enter__, kemudian kendalikan pembersihan dan penyekatan pengecualian dalam __exit__.

Percuma untuk bermula

Pelajari Python dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
76
Pelajaran
320

Soalan Lazim

Adakah pelajaran “Protokol __enter__ dan __exit__” percuma?

Ya — teks penuh “Protokol __enter__ dan __exit__” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Python Academy, tingkat taraf kepada CoddyKit PRO. Kursus Python Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Protokol __enter__ dan __exit__”?

Bina pengurus konteks menggunakan protokol dunder. Anda berlatih Python Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Python Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Python Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.

Berapa lamakah pelajaran “Protokol __enter__ dan __exit__” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Python Academy ini?

Ya. Setiap pelajaran Python Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Pernyataan with secara Mendalam
  2. Protokol __enter__ dan __exit__
  3. contextlib: @contextmanager
  4. Corak Pengurus Konteks Praktikal
← Kembali ke Python Academy