Developer Roadmap
/Common Packages
TopicStep 56 filesOpen folder on GitHub

Common Packages

5.context-manager.md
View on GitHub

CONTEXT MANAGER

With statement

Apa?

Fitur python yang mengatur proses setup dan teardown secara otomatis

Contoh

with open("file.txt") as f:
  data = f.read()

Alasan

  • file akan ditutup otomatis
  • aman dari error
  • tidak perlu try/finally manual
  • lebih rapi dan pythonic

Tanpa context manager

f = open("file.txt")
data = f.read()
f.close()

Jika error terjadi sebelum close(), file tidak akan ditutup menyebabkan

  • memory leak
  • lock file
  • corrupted resource

Dengan context manager

with open("file.txt") as f:
  data = f.read()

saat keluar dari blok with:

  • file ditutup otomatis
  • resource dibersihkan
  • tetap aman meskipun terjadi exception

Bagaimana with bekerja

  • Python memanggil 2 method khusus (dunder)
    • enter()
    • exit()
class Example:
  def __enter__(self):
    print("Entered")
    return self
  
  def __exit__(self, exc_type, exc_value, traceback):
    print("Exited")

Pemakaian

with Example() as e:
  print("Inside")

Membuat context manager sendiri

Contoh timer

import time

class Timer:
  def __enter__(self):
    self.start = time.time()
    return self
  
  def __exit__(self, exc_type, exc, tb):
    self.end = time.time()
    print(f"Time: {self.end - self.start:.4f}s")

Pemakaian

with Timer():
  for _ in range(1_000_000):
    pass

Sangat berguna untuk bencmarking

Context manager dengan contextlib

Membuat context manager dengan generator

from contextlib import contextmanager

@contextmanager
def open_file(name):
  f = open(name)
  try:
    yield f
  finally:
    f.close()

Pemakaian

with open_file("file.txt") as f:
  print(f.read())

Lebih simple lebih bersih

Use case di dunia nyata

  • File handling
  • Database connection Contoh tanpa context
    conn = db.connect()
    try:
      result = conn.execute(...)
    finally:
      conn.close()
    
    Dengan context
    with db.connect() as conn:
      conn.execute(...)
    
  • Locking (threading)
    from threading import Lock
    
    lock = Lock()
    
    with lock:
      # critical section
      counter += 1
    
  • Resouce cleanup di FastAPI / Flask FastAPI dependency
    from contextlib import asynccontextmanager
    
    @asynccontextmanager
    async def lifespan(app):
      print("Starting app...")
      yield
      print("Shutting down...")
    
  • Temporary directory / files
    from tempfile import TemporaryDirectory
    
    with TemporaryDirectory() as tmpdir:
      print("Using temp folder:", tmpdir)
    
  • Redirect stdout (testing)
    from contextlib import redirect_stdout
    import io
    
    f = io.StringIO()
    with redirect_stdout(f):
      print("Hello")
    
    print(f.getvalue())  # "Hello\n"
    
  • Timing, profiling, logging Timer
    with Timer():
      heavy_function()
    
    Logger
    with log_section("loading data"):
      load_data()
    

Handling exceptions inside context manager

Contoh context manager yang men-suppress exception

class IgnoreErrors:
  def __enter__(self):
    pass
  def __exit__(self, exc_type, exc, tb):
    return True  # ignore error

Pemakaian

with IgnoreErrors():
  1 / 0

print("Still running")

Useful untuk test/debug

exit parameters explained

exit(self, exc_type, exc_value, traceback) Jika:

  • tidak ada error - semuanya None
  • ada error - param berisi info error

Jika exit return True, error disuppress Jika return False (default), error tetap dilempar