فصل چهارم: Context Manager، Type Hints و Dataclass

ساده‌سازی با contextlib.contextmanager

نوشتن context manager با یک تابع جنراتور

ماژول contextlib دکوراتوری به نام @contextmanager ارائه می‌دهد که با استفاده از yield می‌توان یک context manager کامل را تنها با یک تابع نوشت، بدون نیاز به کلاس و دو متد جداگانه.

from contextlib import contextmanager
import time

@contextmanager
def timer():
    start = time.time()
    try:
        yield
    finally:
        print(f"زمان سپری‌شده: {time.time() - start:.4f} ثانیه")

with timer():
    total = sum(range(1_000_000))

هر کدی که پیش از yield نوشته شود معادل __enter__ است و هر کدی که بعد از آن (در بلوک finally) بیاید معادل __exit__. اگر داخل بلوک with خطایی رخ دهد، همان خطا در نقطه‌ی yield بازپخش می‌شود، بنابراین استفاده از try/finally برای تضمین اجرای کد پاک‌سازی ضروری است.

ماژول contextlib ابزارهای مفید دیگری نیز دارد، از جمله suppress برای نادیده گرفتن خطاهای خاص و ExitStack برای مدیریت چند context manager به‌صورت پویا. این ابزارها به‌ویژه در کد کتابخانه‌ای و ابزارهای خط فرمان حرفه‌ای بسیار پرکاربرد هستند.

برای ذخیره‌ی پیشرفت و شرکت در آزمون، وارد شوید — رایگان است.