تخطَّ إلى المحتوى

🐍 شرح Python

المولّدات والتكرارات (Generators & Iterators)

الدرس 28 من 30· ⏱ 2 دقائق قراءة

بروتوكول التكرار (Iterator Protocol)

كل حلقة for في بايثون تعمل بنفس الآلية خلف الكواليس: تستدعي iter() على الكائن للحصول على مُكرِّر (iterator)، ثم تستدعي next() عليه مرارًا حتى يرمي استثناء StopIteration:

numbers = [10, 20, 30]
it = iter(numbers)

print(next(it))   # 10
print(next(it))   # 20
print(next(it))   # 30
print(next(it))   # StopIteration ❌ (لا مزيد من العناصر)

هذا بالضبط ما تفعله for x in numbers: تلقائيًّا وتلتقط StopIteration لإنهاء الحلقة بأناقة دون أن تراها.

المولّدات بـ yield

المولّد (generator) دالة عادية تستخدم yield بدل return. بكل استدعاء لها لا تُنفَّذ فورًا — بل تُرجع كائن مولّد يحفظ مكانه ويُكمل من حيث توقّف عند كل next():

def countdown(n):
    while n > 0:
        yield n
        n -= 1

for num in countdown(3):
    print(num)
# 3
# 2
# 1

💡 استدعاء countdown(3) وحده لا يُنفّذ أي كود داخل الدالة — فقط يُنشئ كائن مولّد. الكود يعمل تدريجيًّا مع كل next() أو تكرار for.

لماذا نستخدم المولّدات؟ (كفاءة الذاكرة)

المولّد ينتج القيم واحدة تلو الأخرى عند الطلب، بدل بنائها كلها دفعة واحدة في الذاكرة:

المقارنةقائمة عاديةمولّد (Generator)
بناء القيمكل القيم فورًا في الذاكرةقيمة واحدة عند كل next()
الاستهلاكيمكن المرور عليها عدة مراتتُستهلك مرّة واحدة فقط
مناسبة لـبيانات صغيرة تحتاجها كاملةتدفّق بيانات ضخم أو لا نهائي
def fibonacci():
    a, b = 0, 1
    while True:              # مولّد لا نهائي — آمن لأنه كسول
        yield a
        a, b = b, a + b

fib = fibonacci()
first_five = [next(fib) for _ in range(5)]
print(first_five)   # [0, 1, 1, 2, 3]

بناء قائمة فيبوناتشي لا نهائية بحلقة عادية كان سيُطبق الذاكرة فورًا — المولّد يحلّها لأنه لا يبني شيئًا مسبقًا.

جرّب بنفسك

🐍 محرّر بايثون
📥 المدخلات (input) — قيمة في كل سطر
وحدة التحكّم
اضغط «تشغيل» لرؤية النتيجة هنا.

أخطاء شائعة

  • محاولة إعادة استهلاك مولّد استُنفد بالكامل — يبقى فارغًا، أنشئ مولّدًا جديدًا بدل إعادة استخدام القديم.
  • توقّع أن استدعاء الدالة fibonacci() ينفّذ الكود فورًا — هو فقط يُنشئ كائن المولّد.
  • استخدام list(fibonacci()) مباشرة على مولّد لا نهائي — يعلّق البرنامج للأبد لأنه يحاول استهلاك كل القيم.

🎯 التالي: الديكوريتورز (Decorators) — تعديل سلوك الدوال دون تغيير كودها.

شرح المولّدات والتكرارات (Generators & Iterators) — Python بالعربي
المولّدات والتكرارات (Generators & Iterators)Python بالعربي · The Code Fix

📚 لمزيد من التعمّق في Python، راجِع التوثيق الرسمي لـ Python.

هل كان هذا الدرس مفيدًا؟