مقدمة:
هل سبق لك أن احتجت إلى معالجة كمية ضخمة من البيانات ولكنك واجهت مشكلة في استخدام الذاكرة؟ هل ترغب في توليد قيم متتابعة واحدة تلو الأخرى دون الحاجة إلى تحميل كل القيم دفعة واحدة؟ إذا كانت إجابتك نعم، فإن 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
الخيار المثالي:
-
عند التعامل مع مجموعات بيانات كبيرة:
إذا كنت تعمل مع كمية ضخمة من البيانات (مثل قراءة ملفات كبيرة أو معالجة قواعد بيانات ضخمة)، فإنyield
يسمح لك بتوليد القيم واحدة تلو الأخرى أثناء معالجتها دون الحاجة إلى تخزين كل القيم في الذاكرة. -
توليد قيم غير منتهية:
إذا كنت بحاجة إلى إنشاء تسلسل من القيم يمكن أن يستمر إلى ما لا نهاية، مثل توليد أرقام متتالية أو قيم عشوائية، فإنyield
يتيح لك القيام بذلك بدون تحميل جميع القيم في الذاكرة. -
عند الحاجة إلى تنفيذ عمليات تدريجية أو متتالية:
في بعض الحالات، تحتاج إلى إرجاع القيم في تسلسل تدريجي (مثل حلقات التكرار أو الاستجابة للطلبات تدريجيًا)، مما يسمح لك باستخدامyield
لتوليد كل قيمة عند الطلب دون إيقاف تدفق التنفيذ. -
عند الحاجة إلى تحسين أداء الذاكرة:
عندما تريد تحسين استخدام الذاكرة في البرامج التي تحتاج إلى معالجة كميات كبيرة من البيانات (مثل معالجة النصوص أو الصور أو حتى الاستعلامات من قواعد البيانات)، فإن استخدامyield
بدلاً من تحميل جميع القيم دفعة واحدة في الذاكرة يساهم في تقليل استهلاك الذاكرة بشكل كبير. -
توليد قيم متتابعة في وظائف طويلة المعالجة:
إذا كانت لديك دالة تستغرق وقتًا طويلاً لتنفيذ العمليات (مثل الحسابات المعقدة أو معالجة البيانات)، فإن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
ستمنحك الحل المثالي. تذكر دائمًا أن استخدامها يكون مناسبًا عندما تحتاج إلى تقديم القيم عند الحاجة، مما يعزز من كفاءة البرنامج ويجعله أكثر استجابة ومرونة.