كيفية استخدام "yield" في لغة البايثون

مقدمة:

هل سبق لك أن احتجت إلى معالجة كمية ضخمة من البيانات ولكنك واجهت مشكلة في استخدام الذاكرة؟ هل ترغب في توليد قيم متتابعة واحدة تلو الأخرى دون الحاجة إلى تحميل كل القيم دفعة واحدة؟ إذا كانت إجابتك نعم، فإن yield هي الأداة المثالية لك! في هذا المقال، سنتعرف على كيفية استخدام yield في البرمجة بلغة بايثون، ولماذا تعد الخيار الأمثل عند التعامل مع المولدات والبيانات الكبيرة. ستكتشف كيف توفر yield حلولًا مبتكرة للمبرمجين، مما يجعل من السهل والفعال توليد القيم عند الحاجة دون استهلاك موارد النظام. تابع القراءة لتتعرف على الفرق بين return و yield، وكيف يمكنك الاستفادة من هذه الميزة الرائعة في مشاريعك البرمجية.

تعريف:

كلمة محجوزة في لغة البايثون تستخدم لارجاع قيم متتابعة بخلاف الكلمة المحجوزة return ترجع مجموعة القيم دفعة واحدة وبذلك ينتهي تنفيذ الوظيفة، لكن مع استخدام yield تستمر الوظيفة بالعمل حتى تنتهي بآخر قيمة.

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

الفرق بين "return" و "yield":

تتشابه yield مع return في وظيفة ارجاعها للقيم، لكنها في عملية تصرف الكود عند الوصول اليهما، فـ return توقف تنفيذ الوظيفة؛ أما yield فيستمر الكود بتنفيذ ما بعدها حتى تنتهي تلك الوظيفة.

def func():
    return "افهم" 
    # سيتم ارجاع أول قيمة فقط
    # لن يتم التعرف على أي سطر بعدها
    return "صح" 
            

استخدامها:

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

الوظيفة التي استخدم معها yield واللتي يطلق عليها generator لن يتنفذ الكود الذي بداخلها حتى يتم استهلاكه بواسطة وظيفة أخرى

يتوقف تنفيذ الكود الموجود في نطاق واحد عند وصوله إلى الكلمة المحجوزة return بعد ارجاع النتيجة، لكنه يستمر في التنفيذ عندما يصل إلى yield.

متى أستخدم "yield" في البرمجة بلغة البايثون؟

تستخدم yield في البرمجة بلغة بايثون عندما تحتاج إلى توليد قيم بشكل تدريجي، بدلاً من تخزين جميع القيم في الذاكرة دفعة واحدة. فيما يلي بعض الحالات التي تكون فيها yield الخيار المثالي:

  1. عند التعامل مع مجموعات بيانات كبيرة:
    إذا كنت تعمل مع كمية ضخمة من البيانات (مثل قراءة ملفات كبيرة أو معالجة قواعد بيانات ضخمة)، فإن yield يسمح لك بتوليد القيم واحدة تلو الأخرى أثناء معالجتها دون الحاجة إلى تخزين كل القيم في الذاكرة.

  2. توليد قيم غير منتهية:
    إذا كنت بحاجة إلى إنشاء تسلسل من القيم يمكن أن يستمر إلى ما لا نهاية، مثل توليد أرقام متتالية أو قيم عشوائية، فإن yield يتيح لك القيام بذلك بدون تحميل جميع القيم في الذاكرة.

  3. عند الحاجة إلى تنفيذ عمليات تدريجية أو متتالية:
    في بعض الحالات، تحتاج إلى إرجاع القيم في تسلسل تدريجي (مثل حلقات التكرار أو الاستجابة للطلبات تدريجيًا)، مما يسمح لك باستخدام yield لتوليد كل قيمة عند الطلب دون إيقاف تدفق التنفيذ.

  4. عند الحاجة إلى تحسين أداء الذاكرة:
    عندما تريد تحسين استخدام الذاكرة في البرامج التي تحتاج إلى معالجة كميات كبيرة من البيانات (مثل معالجة النصوص أو الصور أو حتى الاستعلامات من قواعد البيانات)، فإن استخدام yield بدلاً من تحميل جميع القيم دفعة واحدة في الذاكرة يساهم في تقليل استهلاك الذاكرة بشكل كبير.

  5. توليد قيم متتابعة في وظائف طويلة المعالجة:
    إذا كانت لديك دالة تستغرق وقتًا طويلاً لتنفيذ العمليات (مثل الحسابات المعقدة أو معالجة البيانات)، فإن yield يتيح لك توليد القيم أثناء عملية الحساب بدلاً من انتظار إتمامها بالكامل، مما يجعل البرنامج أكثر استجابة.

مثال:

إذا كنت بحاجة إلى معالجة ملف نصي يحتوي على ملايين الأسطر، يمكنك استخدام yield لقراءة السطور واحدة تلو الأخرى بدلاً من تحميلها كلها في الذاكرة:

def read_lines(file_name):
    with open(file_name, 'r') as file:
        for line in file:
            yield line

في هذا المثال، سيتم قراءة السطور من الملف واحدة تلو الأخرى فقط عند الحاجة إليها.

باختصار، yield مثالية عندما تريد توليد القيم تدريجيًا، خاصة عند التعامل مع كميات ضخمة من البيانات أو عندما ترغب في تحسين أداء الذاكرة.

المزايا والعيوب:

المزايا التي تمتاز بها yield:

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

  • توفر مساحات الرام:

    استخدام yield مفيد جدا في توفير المساحة المستخدمة من الرام.

  • استئناف استهلاك العناصر:

    عند استهلاك القيم المرجعة من yield يمكن التوقف ثم العودة والمتابعة من حيث توقف البرنامج

  • توليد حسب الاستهلاك:

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

  • توليد لانهائي:

    بسبب الميزتين الأولى والثانية، تجعل منها فعالة في إنشاء مولد لانهائي

  • متوافق مع حلقات التكرار

    يمكن لحقات التكرار الدوران والعبور علي عناصر الوظائف المولدة

عيوب استخدام yield:

مع كل هذه الميزات السابقة إلى انه لا يزال هناك بعض العيوب التي تحتاج إلى فهمها للتعامل بشكل فعال مع yield.

  • التعقيد:

    في بعض الحالات يصعب فهم الكود عند استخدام yield.

  • دورة واحدة:

    المولدات تعتبر من الكائنات التي يمكن للحلقات المرور عليها، لكنها لدورة واحدة فقط؛ لان المولدات تنشئ القيم استنادا لما قبلها.

  • من البداية:

    لا يمكن الوصول مباشرة الى عنصر في المنتصف دون المرور على العناصر التتي تسبقه في الترتيب داخل المولد.

  • لا يمكن تغيير في موضع محدد:

    بخلاف هياكل البيانات مثل القوائم والمصفوقات، في المولدات لا يمكن تغيير القيمة الموجودة في موضع معين ولا يمكن التوسيع فيها.

تاريخ ظهورها في البرمجة بلغة البايثون:

مفهوم المولدات باستخدام yield بدأ في لغة البايثون اصدار 2.2، والتي تم اصداره في أواخر عام 2001 شهر ديسمبر. حيث شكل ظهورها نقلة نوعية في لغة البايثون، إذ جعل من الممكن توليد تسلسل قيم فرادا كلاً عند طلب استخدامه.

منذ اصدار بايثون 2.2، ولا تزال المولدات تنتشر وتتطور وتحتل جزء كبير من أكواد البايثون عند المطورين. كما استمر دعم المولدات في أحدث اصدارات بايثون 3 أيضا.

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

حول المحتوى:

كلمة محجوزة في لغة البايثون تستخدم لارجاع قيم متتابعة بخلاف الكلمة المحجوزة return ترجع مجموعة القيم دفعة واحدة وبذلك ينتهي تنفيذ الوظيفة، لكن مع استخدام yield تستمر الوظيفة بالعمل حتى تنتهي بآخر قيمة.