مديرو السياق (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 باستدعاء هذه الطرق تلقائيًا، مما يضمن الإعداد والتنظيف بشكل صحيح. هذا مفيد بشكل خاص للملفات، واتصالات قواعد البيانات، والموارد الأخرى التي تتطلب تنظيفًا مضمونًا.
التحدي
سهلفي هذا التحدي، ستقوم بتنفيذ فئة مدير سياق تقيس الوقت المنقضي بين الدخول والخروج من كتلة السياق.
timer.py- يحتوي على تنفيذ فئةTimer(هذا هو الملف الذي ستقوم بتعديله)driver.py- يحتوي على حالات اختبار شاملة (لا تقم بتعديله)
قم بتنفيذ مدير السياق Timer في timer.py باتباع تعليقات TODO. يجب أن تقوم الفئة بما يلي:
- تسجيل وقت البدء عند الدخول إلى السياق
- تسجيل وقت الانتهاء عند الخروج
- حساب وعرض الوقت المنقضي
ورقة مرجعية
تقوم مديرات السياق (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 ثانية
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1أساسيات OOP
الملفات الخارجيةمقدمة في OOPClasses مقابل Objectsمعامل selfMethodsAttributesدالة البناء (__init__)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسيةدالة ()superإعادة تعريف الدوال (Method Overriding)الوراثة المتعددةترتيب استدعاء الدوال (Method Resolution Order)مراجعة - هيكلية الموظفين5تعدد الأشكال
مراجعة إعادة تعريف الدوالمفهوم Duck Typingالأصناف والدوال المجردةتصميم الواجهاتملخص - حاسبة الأشكال8مفاهيم OOP المتقدمة
التركيب مقابل الوراثةMixinsدوال Static و Classمزخرفات Classمديرو السياق (Context Managers)