العائد في Python البرنامج التعليمي: Generator والعائد مقابل مثال الإرجاع
ما هي تفاصيل Python أَثْمَر؟
تعمل الكلمة الأساسية "العائد" في لغة python مثل return مع الكلمة الأساسية الوحيدة
الفرق هو أنه بدلاً من إرجاع قيمة، فإنه يعيد كائن المولد إلى المتصل.
عندما يتم استدعاء دالة ويجد مؤشر التنفيذ كلمة رئيسية yield في الدالة، يتوقف تنفيذ الدالة عند هذا السطر نفسه ويعيد كائن المولد مرة أخرى إلى المتصل.
بناء الجملة
yield expression
الوصف
Python يعيد yield كائن المولد. Generators هي وظائف خاصة يجب تكرارها للحصول على القيم.
تحول كلمة yield التعبيرات المقدمة إلى دالة مولدة تعيد كائن مولد. للحصول على قيم الكائن، يجب تكراره لقراءة القيم المقدمة إلى yield.
مثال: طريقة العائد
هنا مثال بسيط على العائد. تحتوي الدالة testyield() على كلمة رئيسية ذات إنتاجية تحتوي على السلسلة "مرحبًا بك في Guru99 Python الدروس". عندما يتم استدعاء الوظيفة، يتم طباعة الناتج ويعطي كائن مولد بدلاً من القيمة الفعلية.
def testyield(): yield "Welcome to Guru99 Python Tutorials" output = testyield() print(output)
الإخراج:
<generator object testyield at 0x00000028265EB9A8>
المخرجات المقدمة هي كائن مولد، والذي يحتوي على القيمة التي أعطيناها للإنتاج.
ولكننا لا نتلقى الرسالة التي يجب أن نعطيها لتحقيق النتائج!
لطباعة الرسالة المقدمة إلى yield، يجب عليك تكرار كائن المولد كما هو موضح في المثال أدناه:
def testyield():
yield "Welcome to Guru99 Python Tutorials"
output = testyield()
for i in output:
print(i)
الإخراج:
Welcome to Guru99 Python Tutorials
ما هي Generatorق في Python?
Generators هي وظائف تقوم بإرجاع كائن مولد قابل للتكرار. يتم جلب القيم من كائن المولد واحدة تلو الأخرى بدلاً من القائمة الكاملة معًا، وبالتالي للحصول على القيم الفعلية، يمكنك استخدام حلقة for، باستخدام طريقة next() أو list().
باستخدام Generator وظيفة
يمكنك إنشاء مولدات باستخدام دالة المولد واستخدام تعبير المولد.
وظيفة المولد تشبه الوظيفة العادية، فبدلاً من الحصول على قيمة إرجاع سيكون لها كلمة رئيسية yield.
لإنشاء دالة مولدة، يجب عليك إضافة كلمة رئيسية yield. توضح الأمثلة التالية كيفية إنشاء دالة مولدة.
def generator():
yield "H"
yield "E"
yield "L"
yield "L"
yield "O"
test = generator()
for i in test:
print(i)
الإخراج:
H E L L O
الفرق بين الوظيفة العادية v/s Generator وظيفة.
دعونا نفهم كيف تختلف دالة المولد عن الدالة العادية.
هناك دالتين normal_test() و generator_test().
من المفترض أن تقوم كلتا الدالتين بإرجاع السلسلة "Hello World". تستخدم الدالة normal_test() الدالة return بينما تستخدم الدالة generator_test() الدالة yield.
# Normal function
def normal_test():
return "Hello World"
#Generator function
def generator_test():
yield "Hello World"
print(normal_test()) #call to normal function
print(generator_test()) # call to generator function
الإخراج:
Hello World <generator object generator_test at 0x00000012F2F5BA20>
يُظهر الناتج أنه عند استدعاء الدالة العادية normal_test() فإنها تُرجع سلسلة Hello World. بالنسبة لدالة المولد التي تحتوي على كلمة yield فإنها تُرجع وليس السلسلة.
هذا هو الفرق الرئيسي بين دالة المولد والدالة العادية. الآن للحصول على القيمة من كائن المولد، نحتاج إما إلى استخدام الكائن داخل حلقة for أو استخدام طريقة next() أو استخدام list().
print(next(generator_test())) # will output Hello World
هناك فرق آخر يضاف إلى الدالة العادية مقابل دالة المولد وهو أنه عند استدعاء دالة عادية فإن التنفيذ سيبدأ ويتوقف عندما يصل إلى عائد أعلى ويتم إرجاع القيمة إلى المتصل. لذا، عندما يبدأ التنفيذ، لا يمكنك إيقاف الوظيفة العادية بينهما، وسوف تتوقف فقط عندما تأتي عبر الكلمة الأساسية return.
ولكن في حالة وظيفة المولد، بمجرد بدء التنفيذ عند الحصول على العائد الأول، فإنه يتوقف عن التنفيذ ويعيد كائن المولد. يمكنك استخدام كائن المولد للحصول على القيم وأيضًا، إيقافه مؤقتًا واستئنافه وفقًا لمتطلباتك.
كيفية قراءة القيم من المولد؟
يمكنك قراءة القيم من كائن المولد باستخدام list() وحلقة for واستخدام طريقة next().
باستخدام: قائمة ()
القائمة عبارة عن كائن قابل للتكرار يحتوي على عناصره داخل أقواس. سيؤدي استخدام list() على كائن المولد إلى إعطاء جميع القيم التي يحتفظ بها المولد.
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
print(list(num))
الإخراج:
[0, 2, 4, 6, 8]
باستخدام: للداخل
في المثال، توجد دالة مُعرفة باسم even_numbers() والتي ستمنحك جميع الأرقام الزوجية للعدد n المُعرف. سيؤدي استدعاء الدالة even_numbers() إلى إرجاع كائن مولد، يُستخدم داخل حلقة for.
على سبيل المثال:
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
for i in num:
print(i)
الإخراج:
0 2 4 6 8
باستخدام التالي ()
ستمنحك الطريقة التالية () العنصر التالي في القائمة أو المصفوفة أو الكائن. بمجرد أن تصبح القائمة فارغة، وإذا تم استدعاء next()، فسوف يُرجع خطأً بإشارة stopIteration. يشير هذا الخطأ من next() إلى عدم وجود المزيد من العناصر في القائمة.
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))
الإخراج:
0
2
4
6
8
Traceback (most recent call last):
File "main.py", line 11, in <module>
print(next(num))
StopIteration
Generatorيتم استخدامها لمرة واحدة
في حالة المولدات الكهربائية، فهي متاحة للاستخدام مرة واحدة فقط. إذا حاولت استخدامها مرة أخرى، فستكون فارغة.
فمثلا:
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
for i in num:
print(i)
print("\n")
print("Calling the generator again: ", list(num))
الإخراج:
0 2 4 6 8 Calling the generator again: []
في حالة رغبتك في استخدام الإخراج مرة أخرى، سيتعين عليك إجراء الاتصال للعمل مرة أخرى.
على سبيل المثال: Generators والعائد لسلسلة فيبوناتشي
يوضح المثال التالي كيفية استخدام المولدات والعائد في Python. سوف يقوم المثال بإنشاء سلسلة فيبوناتشي.
def getFibonnaciSeries(num):
c1, c2 = 0, 1
count = 0
while count < num:
yield c1
c3 = c1 + c2
c1 = c2
c2 = c3
count += 1
fin = getFibonnaciSeries(7)
print(fin)
for i in fin:
print(i)
الإخراج:
<generator object getFibonnaciSeries at 0x0000007F39C8BA20> 0 1 1 2 3 5 8
مثال: استدعاء الدالة مع العائد
في هذا المثال سوف نرى كيفية استدعاء دالة مع العائد.
يحتوي المثال أدناه على دالة تسمى test() والتي تقوم بإرجاع مربع الرقم المحدد. هناك وظيفة أخرى تسمى getSquare () تستخدم الاختبار () مع الكلمة الأساسية الخاصة بالعائد. يعطي الإخراج القيمة المربعة لنطاق الأرقام المحدد.
def test(n):
return n*n
def getSquare(n):
for i in range(n):
yield test(i)
sq = getSquare(10)
for i in sq:
print(i)
الإخراج:
0 1 4 9 16 25 36 49 64 81
متى يتم استخدام العائد بدلاً من العودة Python
Python3 العائد تعيد الكلمة الأساسية مولدًا إلى المتصل ويبدأ تنفيذ الكود فقط عند تكرار المولد.
A عائد أعلى في دالة هي نهاية تنفيذ الوظيفة، ويتم إرجاع قيمة واحدة إلى المتصل.
هذا هو الموقف الذي يجب عليك فيه استخدام Yield بدلاً من Return
- استخدم العائد بدلاً من العائد عندما يكون حجم البيانات كبيرًا
- يعد العائد هو الخيار الأفضل عندما تحتاج إلى أن يكون التنفيذ أسرع على مجموعات البيانات الكبيرة
- استخدم العائد عندما تريد إرجاع مجموعة كبيرة من القيم إلى وظيفة الاستدعاء
- العائد هو وسيلة فعالة لإنتاج البيانات الكبيرة أو اللانهائية.
العائد مقابل العائد
هنا، هي الاختلافات بين العائد والعائد
| التوزيعات للسهم الواحد | الإرجاع |
|---|---|
| يقوم Yield بإرجاع كائن المولد إلى المتصل، ويبدأ تنفيذ الكود فقط عند تكرار المولد. | العودة في دالة هي نهاية تنفيذ الوظيفة، ويتم إرجاع قيمة واحدة إلى المتصل. |
| عندما يتم استدعاء الدالة وتواجه الكلمة الرئيسية yield، يتوقف تنفيذ الدالة. وتعيد كائن المولد إلى المتصل. سيبدأ تنفيذ الدالة فقط عند تنفيذ كائن المولد. | عندما يتم استدعاء الوظيفة، يبدأ التنفيذ ويتم إرجاع القيمة إلى المتصل إذا كانت هناك كلمة أساسية للإرجاع. تمثل العودة داخل الوظيفة نهاية تنفيذ الوظيفة. |
| تعبير العائد | تعبير العودة |
| لا يتم استخدام الذاكرة عند استخدام الكلمة الأساسية الإنتاجية. | يتم تخصيص الذاكرة للقيمة التي تم إرجاعها. |
| مفيد جدًا إذا كان عليك التعامل مع حجم بيانات ضخم نظرًا لعدم استخدام الذاكرة. | مناسب لحجم البيانات الصغير جدًا. |
| يكون الأداء أفضل إذا تم استخدام الكلمة الرئيسية "العائد" لحجم البيانات الكبير. | يتم استخدام الكثير من الذاكرة إذا كان حجم البيانات ضخمًا مما سيعيق الأداء. |
| يكون وقت التنفيذ أسرع في حالة العائد لحجم البيانات الكبير. | وقت التنفيذ المستخدم أكبر نظرًا لوجود معالجة إضافية في حالة ما إذا كان حجم بياناتك ضخمًا، فستعمل بشكل جيد مع حجم البيانات الصغير. |
ملخص
- تعمل كلمة yield في بايثون مثل كلمة return مع اختلاف وحيد وهو أنه بدلاً من إرجاع قيمة، فإنها تعيد دالة مولد إلى المتصل.
- المولد هو نوع خاص من التكرارات، وبمجرد استخدامه، لن يكون متاحًا مرة أخرى. لا يتم تخزين القيم في الذاكرة ولا تكون متاحة إلا عند استدعائها.
- يمكن قراءة القيم من المولد باستخدام طريقة for-in وlist() وnext().
- الفرق الرئيسي بين yield و return هو أن yield يعيد دالة المولد إلى المتصل و return يعطي قيمة واحدة للمتصل.
- لا يخزن العائد أيًا من القيم في الذاكرة، والميزة هي أنه يكون مفيدًا عندما يكون حجم البيانات كبيرًا، حيث لا يتم تخزين أي من القيم في الذاكرة.
- يكون الأداء أفضل إذا تم استخدام الكلمة الأساسية "العائد" مقارنةً بإرجاع حجم البيانات الكبير.
