![کلمه کلیدی بازده پایتون - چه کاری انجام می دهد؟ [with Examples]](http://learn-programing.ir/wp-content/uploads/2022/09/yield.png)
وقتی تابعی را با a فراخوانی می کنید بازده کلمه کلیدی، کد موجود در تابع این کار را انجام می دهد نه دارم میدوم. به جای آن یک شی مولد ایجاد می شود. می توانید شی مولد را در یک متغیر ذخیره کنید. این شی مولد توانایی اجرای کد در تابع در صورت تقاضا را دارد.
وقتی شی مولد را فرا می خوانید، پایتون کد موجود در تابع مولد را اجرا می کند یک بار. وقتی وجود داشته باشد متوقف می شود بازده کلمه کلیدی و یک مقدار را به تماس گیرنده تحویل می دهد.
وقتی دوباره ژنراتور را فرا می خوانید، اجرا از جایی که متوقف شده ادامه می یابد. به عبارت دیگر، پایتون دوباره تابع را اجرا می کند و در تابع بعدی متوقف می شود بازده کلمه کلیدی و دوباره مقدار را ارائه می دهد.
این روند تا زمانی ادامه می یابد که دیگر مقادیری برای استخراج وجود نداشته باشد.
تابعی که از a استفاده می کند بازده کلمه کلیدی یک تابع مولد است. ژنراتورها زمانی مفید هستند که نیاز به تکرار مقادیر بدون ذخیره آنها در حافظه دارید.
این راهنما به شما می آموزد که چه بازده کلیدواژه در سطح بالایی بدون جزئیات فنی تکرارکننده ها و تکرارشونده ها عمل می کند.
چرا بازده در پایتون؟
را بازده کلمه کلیدی هنگام حلقه زدن از طریق یک گروه بزرگ از مقادیر مفید است. دلیلی که ممکن است بخواهید از آن استفاده کنید بازده بجای برگشت به کارایی حافظه ختم می شود.
فرض کنید تابعی دارید که یک فایل متنی را برای چاپ هر کلمه در کنسول می خواند. برای انجام این کار به روش سنتی، شما باید کلمات را در یک لیست ذخیره کنید و در لیست حلقه بزنید، درست است؟
اما اگر حدود 1 میلیارد کلمه در فایل وجود داشته باشد چه؟
یک برنامه پایتون نمی تواند لیستی از 1 میلیارد کلمه را مدیریت کند. به این ترتیب شما نمی توانید کلمات را در یک لیست ذخیره کنید! برای غلبه بر این مشکل، به مکانیزمی نیاز دارید که در آن مجبور نباشید کلمات را در یک لیست ذخیره کنید، اما همچنان بتوانید آنها را حلقه بزنید.
اینجاست که می توانید از ژنراتورها استفاده کنید، یعنی توابعی که بازده ارزش های.
ایده مولد این نیست که همه کلمات را یکجا در حافظه ذخیره کند. در عوض، مولد مجموعه را کلمه به کلمه مرور می کند. فقط کلمه فعلی را در حافظه ذخیره می کند. او همچنین می داند که چگونه مورد بعدی را بدست آورد. به این ترتیب، مولد میتواند لیست 1 میلیارد کلمهای را بدون هیچ مشکلی در مصرف حافظه مرور کند. در تئوری، شما می توانید از یک مولد مانند این برای چرخش بین تعداد بی نهایت کلمه استفاده کنید، زیرا عملاً به حافظه ای نیاز نیست.
بهترین بخش این است که نحو ژنراتور شبیه به پیاده سازی به نظر می رسد برای … در حلقه در یک لیست بنابراین حتی اگر مکانیسم کاملا متفاوت است، نحو باقی می ماند.
یک مثال
وقتی تابعی را با a فراخوانی می کنید بازده کلمه کلیدی، شما ایجاد یک مولد شی. وقتی این شی مولد را فرا میخوانید (مثلاً با استفاده از یک حلقه for)، اساساً از آن میخواهید که مقدار بعدی را در مجموعه مقادیری که در آن حلقه میزنید برگرداند. این روند تا زمانی ادامه می یابد که هیچ مقداری باقی نماند.
به عنوان مثال، در اینجا یک تابع مولد است که لیستی از اعداد را مربع می کند
def square(numbers): for n in numbers: yield n ** 2
حالا بیایید این تابع را فراخوانی کنیم و نتیجه را چاپ کنیم:
squares = square([1, 2, 3, 4, 5]) print(squares)
خروجی:
<generator object square at 0x7fd8f4dff580>
ممکن است فکر کنید که این جسم مربع های اعداد را ذخیره می کند [1, 2, 3, 4, 5]، درست؟ اما این طوری نیست! را مربع ها شی یک مقدار واحد را ذخیره نمی کند، و نه یک مربع واحد در جایی محاسبه شده است. در عوض، شی مولد به شما امکان می دهد مربع ها را در صورت تقاضا محاسبه کنید.
برای محاسبه واقعی مربع ها، باید شی مولد را فراخوانی کنید. یکی از راه های انجام این کار استفاده از داخلی است بعد() عملکرد. این تابع از مولد می خواهد که مقدار مجذور بعدی را محاسبه کند.
بیا تماس بگیریم بعد() پنج بار عمل کنید و نتایج را چاپ کنید:
print(next(squares)) print(next(squares)) print(next(squares)) print(next(squares)) print(next(squares))
خروجی:
1 4 9 16 25
همانطور که می بینید، همه بعد() فراخوانی تابع مقدار مربع بعدی را در لیست برمی گرداند. به عبارت دیگر، همه بعد() تماس اجرا می شود مربع() یک بار برای محاسبه و ارائه مقدار مربع صحیح عمل کنید.
اما چگونه می داند که کدام مقدار را محاسبه کند؟
شی مولد به خاطر می آورد که از آخرین باری که کسی next() را روی آن فراخوانی کرد کجا رفته است. اینگونه می داند که چگونه مقدار بعدی را به درستی انتخاب کند.
اما همین بعد() چیزی در مورد ویژگی کمی گیج کننده است، اینطور نیست؟ مطمئن! در واقع، شما نباید استفاده کنید بعد() عملکرد مولد تکرار درعوض، میتوانید از حلقه for قدیمی برای فراخوانی ژنراتور استفاده کنید.
def square(numbers): for n in numbers: yield n ** 2 squares = square([1, 2, 3, 4, 5]) for square in squares: print(square)
خروجی:
1 4 9 16 25
توجه داشته باشید که حلقه for فراخوانی می کند بعد() عملکرد ژنراتور در پشت صحنه این کار را تا زمانی انجام می دهد که هیچ مقداری برای محاسبه ژنراتور وجود نداشته باشد.
امیدوارم الان بهتر بفهمی بازده کلمه کلیدی.
در مرحله بعد، بیایید نگاهی گذرا به نحوه درک بهتر هدف تابع استخراج بیاندازیم.
میانبری برای درک استخراج در عمل
اگر با ژنراتورها و بازدهی آشنا نیستید، در اینجا ترفندی وجود دارد که میتوانید انجام دهید تا بفهمید کد بازده چه میکند.
توجه داشته باشید که این ترفند جایگزینی معادل صورت سود و زیان نیست! اما در عوض، به شما کمک می کند درک کنید که اگر کدی را که از آن استفاده می کنید راحت نیستید، چه کاری انجام می دهد بازده کلمه کلیدی.
این شکار است. وقتی می بینید یک بازده کلمه کلیدی:
- این خط را به عنوان اولین خط تابع اضافه کنید: نتیجه = [].
- همه را جایگزین کنید بازده val بیان با result.append(val).
- اضافه کردن نتیجه برگشت به پایین تابع
- حالا تابع را بخوانید و ببینید چه کاری انجام می دهد.
- تابع را با اصلی مقایسه کنید.
بیایید نمونه ای از اعمال این ترفند را در یک تابع با مشاهده کنیم بازده کلمه کلیدی. در اینجا مثالی از یک تابع ژنراتور آورده شده است:
def square(numbers): for n in numbers: yield n ** 2
برای اینکه ببینیم این تابع چه کاری انجام می دهد، مراحل بالا را برای تابع اعمال می کنیم:
1. اضافه کنید نتیجه = [] تا شروع عملکرد
def square(numbers): result = [] for n in numbers: yield n ** 2
2. تغییر دهید بازده val با result.append(val).
def square(numbers): result = [] for n in numbers: result.append(n ** 2)
3. اضافه کنید نتیجه برگشت به پایین تابع
def square(numbers): result = [] for n in numbers: result.append(n ** 2) return result
4. تابع را بخوانید و بفهمید چه کار می کند.
بنابراین اکنون به وضوح می توانید ببینید که این تابع لیستی از اعداد را می گیرد، اعداد را مربع می کند و لیستی از اعداد مربع را برمی گرداند.
درک این نکته مهم است که این اصلاح است نه جایگزینی تابع تورفتگی! در عوض، به شما کمک می کند کد اصلی را بهتر درک کنید.
برای اینکه به طور کامل بفهمید کلمه کلیدی بازده چه کاری انجام می دهد، باید بدانید که تکرار کننده ها، تکرار کننده ها و مولدها چیست. در اینجا راهنمای کاملی است که باید بخوانید.
نتیجه
را بازده کلمه کلیدی یک راه کارآمد حافظه برای حلقه زدن مجموعه بزرگی از مقادیر است. عملکرد با بازده کلمه کلیدی ژنراتور نامیده می شود.
تابع مولد مقادیر تکرار شده را در حافظه ذخیره نمی کند. در عوض، به ارزش فعلی اهمیت می دهد و می داند که چگونه ارزش بعدی را بدست آورد. این باعث می شود که تعداد زیادی از مقادیر را حلقه کنید. شما فقط برای یک مقدار به حافظه نیاز دارید.
هنگام تکرار بر روی یک شی مولد، می توانید سینتکس حلقه for سنتی را اعمال کنید. هنگامی که این کار را انجام می دهد، ژنراتور مقادیر را در پرواز تولید می کند.