Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

مديرو السياق (Context Managers)

جزء من قسم البرمجة كائنية التوجه في رحلة Python على Coddy. الدرس 41 من 64.

تتيح لك مدراء السياق تخصيص resources وتحريرها في الوقت المطلوب بدقة. وتضمن إجراء التنظيف المناسب حتى في حال حدوث أخطاء.

إليك المثال الأكثر شيوعًا باستخدام عبارة with:

with open('example.txt', 'w') as file:
    file.write('Hello, world!')
# يتم إغلاق الملف تلقائيًا هنا

يتم إغلاق file automatically بعد الكتلة، حتى إذا حدث exception.

أنشئ مدير السياق الخاص بك من خلال تنفيذ أسلوبي __enter__ و__exit__:

class MyContext:
    def __enter__(self):
        print("Entering the context")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exiting the context")
        return False  # لا تكبت الاستثناءات

استخدم مدير السياق المخصص لديك:

with MyContext() as ctx:
    print("Inside the context")

المخرجات:

Entering the context
Inside the context
Exiting the context

أنشئ مدير سياق عمليًا أكثر لاتصالات قاعدة البيانات:

class DatabaseConnection:
    def __init__(self, db_name):
        self.db_name = db_name
        self.connection = None
    
    def __enter__(self):
        print(f"Connecting to {self.db_name}")
        self.connection = f"Connection to {self.db_name}"
        return self.connection
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"Closing connection to {self.db_name}")
        self.connection = None

with DatabaseConnection("users_db") as conn:
    print(f"Using {conn}")
    print("Performing database operations...")

التعامل مع الاستثناءات في مديري السياق:

class SafeContext:
    def __enter__(self):
        print("Setting up resources")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Cleaning up resources")
        if exc_type:
            print(f"An exception occurred: {exc_val}")
        return False  # لا تقم بقمع الاستثناء

with SafeContext():
    print("Working with resources")
    # raise ValueError("Something went wrong")  # أزل التعليق للاختبار

الناتج:

Connecting to users_db
Using Connection to users_db
Performing database operations...
Closing connection to users_db
Setting up resources
Working with resources
Cleaning up resources

تتلقى الطريقة __exit__ ثلاث معلمات:

  • exc_type: نوع الاستثناء (أو None)
  • exc_val: قيمة الاستثناء (أو None)
  • exc_tb: تتبّع الاستثناء (أو None)

النقطة الأساسية: تستخدم مدراء السياق أساليب __enter__ و__exit__ لإدارة الموارد. تستدعي عبارة with هذه الأساليب تلقائيًا، مما يضمن الإعداد والتنظيف المناسبين. وهذا مفيد بشكل خاص للملفات واتصالات قواعد البيانات والموارد الأخرى التي تحتاج إلى تنظيف مضمون.

challenge icon

التحدي

سهل

في هذا التحدي، ستنفّذ class مدير context يقيس elapsed time بين entering وexiting كتلة context.

  • timer.py - يحتوي على تنفيذ class Timer (هذا هو الملف الذي ستعدّله)
  • driver.py - يحتوي على حالات اختبار شاملة (لا تعدّله)

نفّذ مدير context Timer في timer.py باتباع تعليقات TODO. يجب أن تقوم class بما يلي:

  1. تسجّل start time عند entering إلى context
  2. تسجّل end time عند exiting
  3. تجري Calculate لـ elapsed time وتعرضه

جرّب بنفسك

from timer import Timer
import time

# معالج حالة الاختبار
test_case = input()

if test_case == "basic_test":
    # اختبار الوظائف الأساسية
    with Timer():
        # محاكاة بعض العمل
        time.sleep(2)  # هذا يجعل البرنامج ينتظر لمدة ثانيتين

elif test_case == "nested_contexts":
    # اختبار مديري السياق المتداخلين
    with Timer():
        time.sleep(1)
        with Timer():
            time.sleep(1)

elif test_case == "exception_handling":
    # اختبار معالجة الاستثناءات داخل السياق
    try:
        with Timer():
            time.sleep(1)
            raise ValueError("Test exception")
    except ValueError as e:
        print(f"Caught exception: {e}")

elif test_case == "zero_sleep":
    # اختبار مع نوم أدنى
    with Timer():
        time.sleep(0.001)

elif test_case == "multiple_timers":
    # اختبار مؤقتات متعددة بالتسلسل
    with Timer():
        time.sleep(1)
    
    with Timer():
        time.sleep(0.5)
    
    with Timer():
        time.sleep(2)

elif test_case == "as_decorator":
    # اختبار المؤقت في سياق دالة
    def timed_function():
        with Timer():
            time.sleep(2)
    
    timed_function()

else:
    # الاختبار الافتراضي - الوظائف الأساسية
    with Timer():
        # محاكاة بعض العمل
        time.sleep(2)  # هذا يجعل البرنامج ينتظر لمدة ثانيتين
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Python عبر الإنترنت