EMZETT.
Giriş yap

Bağlam yöneticileri ve with: kaynakları güvenle açmak ve kapatmak

Kısaca: with ifadesi, dosyalar, bağlantılar veya kilitler gibi kaynakların hatada bile yeniden serbest bırakılmasını sağlar; kendi bağlam yöneticilerini sınıflarla veya contextlib ile kurarsın.

Biraz daha ayrıntılı: Bir dosyayı açan onu kapatmalıdır, aksi hâlde tutamaçlar açık, veriler yazılmamış, kilitler tutulmuş kalır. try/finally çalışır ama hantaldır. with bunu otomatik yapar.

Ayrıntılı

Kalıp

with open("data.txt", encoding="utf-8") as f:
    content = f.read()
# burada dosyanın istisna olsa bile kapalı olduğu garanti

try: ... finally: f.close() ile eşdeğerdir. Birkaç kaynak: with open(a) as x, open(b, "w") as y:. Tipik bağlam yöneticileri: dosyalar, threading.Lock(), veri tabanı bağlantıları/işlemleri (with conn:), tempfile.TemporaryDirectory(), socket, zipfile, unittest.mock.patch, subprocess, HTTP oturumları (requests.Session).

Kendi bağlam yöneticilerin

__enter__ ve __exit__ ile sınıf:

import time
class Stopwatch:
    def __enter__(self):
        self.start = time.perf_counter(); return self
    def __exit__(self, typ, value, tb):
        print(f"{time.perf_counter() - self.start:.3f}s")
        return False        # istisnayı yutma

contextlib ile üreteç:

from contextlib import contextmanager
@contextmanager
def workdir(path):
    old = os.getcwd(); os.chdir(path)
    try:
        yield
    finally:
        os.chdir(old)

__exit__ istisna bilgisini alır; True döndürmek onu bastırır (nadiren mantıklı; contextlib.suppress(FileNotFoundError) güvenli varyanttır).

Daha fazla araç

  • contextlib.closing, ExitStack (dinamik olarak çok kaynak), redirect_stdout.
  • async: eşzamansız kaynaklar için async with (veri tabanı havuzu, HTTP istemcisi aiohttp), __aenter__/__aexit__.
  • Dosyalar: Path.read_text() tek satırlıklar için with’i sarar.
  • İşlemler: with db.transaction(): commit/rollback’i otomatik yapar.
  • Testler: with pytest.raises(ValueError):, with patch(...).
  • Kilit: with lock: unutulmuş bir release()’i önler (bkz. mutex/deadlock).

Tipik hatalar ve ipuçları

  • Bir dosyayı with olmadan açık bırakmak (Windows bunu silemez).
  • with bloğundan dönmek sorun değildir: __exit__ yine çalışır.
  • try/finally olmayan bir üreteç bağlam yöneticisi istisnada temizlik yapmaz.
  • İstisnaları yutma: __exit__ False/None döndürür.
  • Metin açarken her zaman encoding ver.
  • Kaynak sızıntıları ResourceWarning/-X dev ile tespit edilir.
  • İlgili: RAII (C++), try-with-resources (Java), defer (Go), using (C#).

Ayrıca bak: Python’da dosyalar, Mutex