محتويات الدورة

بايثون / أنظمة قابلة للصيانة / الدرس 14

المولدات والتفويض والتدفقات المحدودة

ابن منتجين كسولين، وافهم التعليق والتنظيف، ووضح ضغط الاستهلاك وملكية الموارد في التدفقات.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • المولد حساب معلّق
  • التنظيف وتوقيت الفشل

المولد حساب معلّق

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

الاستهلاك يتحكم في التقدم

يطلب المستهلك القيمي عنصرا في كل مرة، فلا يتقدم المنتج بلا حد عبر التكرار العادي. يقدم ذلك ضغطا عكسيا بسيطا في الخطوط المتزامنة. قد تخزن المراحل الوسيطة البيانات، ويزيل حفظ كل الناتج ميزة الذاكرة. قد يكون المصدر محدودا أو ضخما أو لا نهائيا؛ لا يعني الطلب المحدود محدودية المصدر. استخدم شرط توقف مثل islice. وإذا كان إنتاج العنصر مكلفا، فلا يصبح الإلغاء ملحوظا إلا عند نقاط التحقق أو التعليق المصممة.

إنتاج متتالية محدودة

ينتج المثال المجاميع الجارية ويحفظ المجمّع بين الطلبات. ينشئ الاستدعاء مولدا دون استهلاك القيم بعد. ينفذ أخذ نتيجتين العمل اللازم لهما فقط، ثم يستأنف المستهلك اللاحق الحساب نفسه. تفيد هذه الحالة المحفوظة في التدفقات، لكنها تحتاج توثيقا عند مشاركة المولد. لا يحصل مستهلك ثان على تقدم خاص به. لدعم إعادة التشغيل احفظ نسخة مناسبة أو أنشئ مولدا جديدا من مصدر قابل للإعادة، مع إدراك تكلفة الذاكرة أو تكرار العمل.

python إنتاج متتالية محدودة — مثال محلول
from itertools import islice

def running_totals(values):
    total = 0
    for value in values:
        total += value
        yield total

stream = running_totals([2, 3, 5])
print(list(islice(stream, 2)))
print(list(stream))
الناتج المتوقع
[2, 5]
[10]

يبقى المجموع خمسة بعد طلبين. يضيف الاستئناف الخمسة الأخيرة ويعطي عشرة دون إعادة البداية.

التفويض مع حفظ القصد

تفوض yield from التكرار إلى قابل آخر، وتتجاوز في بروتوكول المولد الكامل مجرد الاختصار. توضح هنا تمرير كل قيمة من مصدر فرعي. يحافظ المثال على ترتيب مجموعتين محدودتين، ولا يدعي تسطيح مدخلات عشوائية عميقة؛ فهذا يحتاج قواعد للنص والبايتات والقواميس والدورات. حدد عقد المدخل بدلا من تخمين ما يقصده المستدعي. وعند تفويض مولد يملك موردا، افهم انتشار النفاد وclose والاستثناءات في السلسلة.

python التفويض مع حفظ القصد — مثال محلول
def concatenate(groups):
    for group in groups:
        yield from group

print(list(concatenate([[1, 2], [], [3]])))
الناتج المتوقع
[1, 2, 3]

يمرر التفويض المجموعات بالترتيب ولا تضيف الفارغة قيما. هذا وصل بمستوى واحد وفق عقد محدود لمجموعات متتابعة.

التنظيف وتوقيت الفشل

قد يبقي المولد ملفا مفتوحا أثناء التعليق داخل with. إذا توقف المستهلك مبكرا فلا تعتمد على جمع القمامة الفوري؛ حدد الملكية بمدير سياق أو غلاف إغلاق مناسب. تستطيع finally تحرير الموارد عند إغلاق المولد. تظهر أخطاء المرحلة الكسولة أثناء التكرار، فلا يثبت بناء الخط صلاحية السجلات المقبلة. اختبر النفاد والتوقف المبكر والفراغ والفشل بعد إخراج قيم. حدد هل تقبل النتائج الجزئية أم يجب التحقق قبل النشر.

الأخطاء الشائعة وإصلاحها

عدم ظهور عمل بعد إنشاء المولد

لماذا يحدث؟
ينشئ الاستدعاء مكررا معلقا فقط.
كيف تصلحه؟
استهلكه بالتكرار أو next وفق خطة محدودة.
كيف تتجنب تكراره؟
ميز بناء الخط من تنفيذه في الاختبارات.

بقاء مورد مفتوحا بعد break مبكرة

لماذا يحدث؟
لا يزال المولد المعلق يملك المورد.
كيف تصلحه؟
أغلقه بملكية صريحة أو غلف العمر بمدير سياق.
كيف تتجنب تكراره؟
ضم تنظيف التوقف المبكر إلى العقد والاختبار.

تعليق تحويل مصدر لا نهائي إلى قائمة

لماذا يحدث؟
يطلب الحفظ كل القيم المقبلة.
كيف تصلحه؟
استهلك بادئة أو نافذة مجال محدودة.
كيف تتجنب تكراره؟
سجل افتراض المحدودية لكل عملية استهلاك.

اختبر فهمك

1. فسر مولدا يعطي أول ثلاثة مجاميع جارية من [1, 2, 3, 4].

اعرض الحل المشروح

استخدم running_totals واستهلك list(islice(stream, 3)). النتيجة [1, 3, 6]. لم يعالج الطلب المدخل الرابع بعد؛ يعطي طلب لاحق على التدفق نفسه 10، فيوضح الحالة المعلقة لا مخرجات محسوبة مسبقا.

2. لماذا قد يفوت التقاط الأخطاء حول إنشاء المولد مدخلا تالفا؟

اعرض الحل المشروح

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

أهم ما تعلمته

  • تحفظ المولدات الحالة المحلية عبر yield.
  • ينقل الكسل العمل والفشل إلى وقت الاستهلاك.
  • حدد الاستهلاك ووضح ملكية التنظيف.

المراجع الرسمية