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

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

جزء من قسم Object Oriented Programming في رحلة Python على Coddy — الدرس 41 من 64.

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

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

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

يتم إغلاق الملف تلقائيًا بعد الكتلة البرمجية، حتى في حالة حدوث استثناء.

أنشئ مدير السياق (context manager) الخاص بك عن طريق تنفيذ الدوال __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

قم بإنشاء مدير سياق (context manager) أكثر عملية لاتصالات قاعدة البيانات:

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...")

معالجة الاستثناءات في مديري السياق (context managers):

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)

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

challenge icon

التحدي

سهل

في هذا التحدي، ستقوم بتنفيذ فئة مدير سياق تقيس الوقت المنقضي بين الدخول والخروج من كتلة السياق.

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

قم بتنفيذ مدير السياق Timer في timer.py باتباع تعليقات TODO. يجب أن تقوم الفئة بما يلي:

  1. تسجيل وقت البدء عند الدخول إلى السياق
  2. تسجيل وقت الانتهاء عند الخروج
  3. حساب وعرض الوقت المنقضي

ورقة مرجعية

تقوم مديرات السياق (Context managers) بتخصيص الموارد وتحريرها بدقة عند الحاجة، مما يضمن التنظيف المناسب حتى في حالة حدوث أخطاء.

استخدم عبارة with لإدارة الموارد تلقائيًا:

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

قم بإنشاء مديرات سياق مخصصة من خلال تنفيذ طريقتي __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")

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

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

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

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  # لا تقم بكتم الاستثناء

جرّب بنفسك

from timer import Timer
import time

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

if test_case == "basic_test":
    # اختبار الوظائف الأساسية
    with Timer():
        # محاكاة بعض العمل
        time.sleep(2)  # هذا يجعل البرنامج ينتظر لمدة 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":
    # اختبار مع أقل مدة 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)  # هذا يجعل البرنامج ينتظر لمدة 2 ثانية
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming