تكرار السؤال: …
الإجابة المختصرة
الـ generator ينتج القيم عند الطلب واحدة تلو الأخرى بدل بناء collection كاملة، فتبقى الذاكرة ثابتة تقريبًا مهما كبر حجم البيانات.
الشرح
عند الوصول إلى yield تتوقف الدالة وتحفظ حالتها المحلية، ثم تستأنف من نفس النقطة عند طلب العنصر التالي. هذا مثالي لمعالجة ملفات ضخمة أو تدفقات بيانات على مراحل (pipeline). المقابل: لا يوجد وصول عشوائي بالفهرس، ولا يمكن معرفة الطول مسبقًا، والأخطاء تظهر أثناء الاستهلاك وليس عند إنشاء الـ generator. ويسمح yield from بتفويض التوليد إلى generator آخر.
مثال بالكود
def read_errors(path):
with open(path, encoding="utf-8") as f:
for line in f: # سطر بسطر
if "ERROR" in line:
yield line.rstrip()
for entry in read_errors("app.log"):
print(entry)أخطاء شائعة
- استدعاء list() على generator لملف ضخم مما يلغي الفائدة ويستهلك الذاكرة.
- توقع أن يظهر الخطأ عند إنشاء الـ generator بينما يظهر عند أول next().