الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

ماهي استخدامات yield

بدأه m ahmed في 10 يوليو 2014 · 3 رد · 1,932 مشاهدة · في لغة Python
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

من خلال بحثي ماعرفته عن yield انها مثل return
لكن لو سمحتم اريد مثال شامل يوضح معناها
واذا كانت مثل return هل تستخدم خارج الدالة؟

def a():    for i in range(10):        yield i

في هذا المثال مالفائدة اذا كان استخدامها بهذه الطريقة فقط

for i in a():    print(i)
#2

بدونها ربما ستكتب شيء مثل:

>>> def a():
...     lst = []
...     for i in range(10):
...             lst.append(i)
...     return lst
...
>>>
>>> a()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>

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

 

الحل الوسط أن تعيد له مولد لهذه العناصر والمستخدم يستخدمه لما يناسبه، ففي النهاية المهم هي العناصر وليس القالب الذي يحويها.

 

yield تجعل الدالة كما قلت تعيد كائن مولد generator (نوع من أنواع المكررات iterators) يولد هذه الأرقام على رقم رقم:

>>> def a():
...     for i in range(10):
...             yield i
...
>>>
>>> a()
<generator object a at 0x01ECF6E8>
>>>

يمكن استخدام الوظيفة __next__ في هذا الكائن المعاد لتويد الرقم التالي او استخدام الدالة next (تستدعي __next__ داخلياً):

>>> a()
<generator object a at 0x01ECF6E8>
>>>
>>> g = a()
>>> next(g) # or g.__next__()
0
>>> next(g) # or g.__next__()
1
>>> next(g) # or g.__next__()
2
...
8
>>> next(g) # or g.__next__()
9
>>> next(g) # or g.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

عند الإنتهاء من توليد آخر قيمة سنتج استثناء StopIteration.

 

الآن لاحاجة لتويد كل الأرقام كما في الدالة الأولى وتخزينها في list ثم تحويلها لـtuple، تعيد مولد والمستخدم يحولها لما يريد (الدوال التي كانت تعيد list في بايثون 2 أصبحت تعيد generators في بايثون 3 لهذا السبب):

>>> list(a())
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> tuple(a())
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>>>

ولسنا مضظرين لتوليد كل العناصر كي نحصل فقط على أول خمسة أرقام:

>>> g = a()
>>> n = 0
>>> while n < 5:
...     print(next(g))
...     n += 1
...
0
1
2
3
4
>>>

الـgenerator طريقة من طرق إنشاء المكررات iterators، ربما تقرأ عنها أولاً.

1
#3

شكرا لك على الشرح وجارى الإطلاع عليه :) :) 

#4

حتى تفهم الامرyield  جيدا ، يجب ان تفهم الفرق بينه وبين return المستخدم في ارجاع قيم الدوال

 

عند تنفيذ دالة ما . فان بايثون يقوم بحجز مساحة في الذاكرة namespace ليضع فيها المتغيرات المحلية local variables الخاصة بالدالة.

 

بعد استدعاء الدالة يقوم بايثون او بالتحديد الامرreturn يقوم بحذف جميع المتغيرات المحلية التي انشاءها سابقا وارجاع قيمة الدالة .
 
اما عند استخدام الامر yield فان المتغرات المحلية لا يتم تدميرها عند الخروج من الدالة وهذا يسمح بالرجوع الى الدالة وتكملة تنفيذها انطلاقا من الحالة التي تركناها فيها اخر مرة

تم تعديل هذه المشاركة بواسطة med reda في 12 يوليو 2014 في 05:10

مواضيع مشابهة