کلمه کلیدی "عملکرد" چه کاری انجام می دهد؟

ساخت وبلاگ

آیا می خواهید این پست را بهبود ببخشید؟پاسخ های مفصلی به این سؤال ، از جمله استنادها و توضیح اینکه چرا پاسخ شما صحیح است ارائه دهید. پاسخ بدون جزئیات کافی ممکن است ویرایش یا حذف شود.

استفاده از کلمه کلیدی عملکرد در پایتون چیست؟چه کار میکند؟

به عنوان مثال ، من سعی می کنم این کد 1 را درک کنم:

و این تماس گیرنده است:

چه اتفاقی می افتد که روش _get_child_candidates خوانده شود؟آیا لیستی برگردانده شده است؟یک عنصر واحد؟آیا دوباره خوانده می شود؟چه زمانی تماس های بعدی متوقف می شود؟

1. این قطعه کد توسط Jochen Schulz (Jrschulz) نوشته شده است ، که یک کتابخانه عالی پایتون را برای فضاهای متریک تهیه کرده است. این پیوند به منبع کامل است: Module MSPACE.

51 پاسخ 51

برای درک اینکه عملکرد چه کاری انجام می دهد ، باید درک کنید که ژنراتورها چیست. و قبل از اینکه بتوانید ژنراتورها را درک کنید ، باید تکرار را درک کنید.

تکرار

هنگامی که یک لیست ایجاد می کنید ، می توانید موارد آن را یک به یک بخوانید. خواندن موارد آن یکی یکی به نام تکرار نامیده می شود:

MyList یک تکرار است. هنگامی که از یک لیست درک لیست استفاده می کنید ، یک لیست ایجاد می کنید ، و بنابراین یک تکرار پذیر:

هر چیزی که می توانید از "برای" استفاده کنید. "لیست ها ، رشته ها ، پرونده ها.

این تکرار کننده ها مفید هستند زیرا می توانید آنها را به همان اندازه که می خواهید بخوانید ، اما تمام مقادیر موجود در حافظه را ذخیره می کنید و این همیشه چیزی نیست که می خواهید وقتی ارزش های زیادی دارید.

ژنراتور

ژنراتورها تکرارها هستند ، نوعی تکرار شونده که فقط یک بار می توانید تکرار کنید. ژنراتورها تمام مقادیر موجود در حافظه را ذخیره نمی کنند ، آنها مقادیر را در پرواز تولید می کنند:

این فقط یکسان است به جز استفاده () به جای []. اما ، شما نمی توانید بار دوم برای من در MyGenerator اجرا کنید زیرا ژنراتورها فقط یک بار قابل استفاده هستند: آنها 0 را محاسبه می کنند ، سپس آن را فراموش کرده و 1 را محاسبه می کنند و محاسبه 4 ، یک به یک را پایان می دهند.

بازده

بازده کلمه کلیدی است که مانند بازگشت استفاده می شود ، به جز عملکرد یک ژنراتور را برمی گرداند.

در اینجا یک مثال بی فایده است ، اما وقتی می دانید که عملکرد شما مجموعه عظیمی از ارزش ها را برمی گرداند که فقط باید یک بار بخوانید.

برای تسلط بر عملکرد ، باید درک کنید که وقتی عملکرد را فراخوانی می کنید ، کدی که در بدنه عملکرد نوشتید اجرا نمی شود. این تابع فقط شیء ژنراتور را برمی گرداند ، این کمی مشکل است.

سپس ، کد شما از جایی که هر بار برای استفاده از ژنراتور استفاده می شود ، ادامه خواهد یافت.

اکنون قسمت سخت:

اولین باری که برای تماس با شیء ژنراتور ایجاد شده از عملکرد شما تماس می گیرد ، از ابتدا کد را در عملکرد شما اجرا می کند تا اینکه به بازده برسد ، سپس اولین مقدار حلقه را برمی گرداند. سپس ، هر تماس بعدی تکرار دیگری از حلقه ای را که در عملکرد نوشتید اجرا می کند و مقدار بعدی را برمی گرداند. این کار تا زمانی که ژنراتور خالی در نظر گرفته شود ادامه خواهد یافت ، که وقتی عملکرد بدون ضربه زدن به عملکرد انجام می شود ، اتفاق می افتد. این می تواند به این دلیل باشد که حلقه به پایان رسیده است ، یا به این دلیل که دیگر "if/other" را برآورده نمی کنید.

کد شما توضیح داد

این کد شامل چندین قسمت هوشمند است:

حلقه در یک لیست تکرار می شود ، اما در حالی که حلقه تکرار می شود ، لیست گسترش می یابد. این یک روش مختصر برای عبور از همه این داده های تو در تو است حتی اگر کمی خطرناک باشد زیرا می توانید با یک حلقه نامحدود به پایان برسید. در این حالت ، نامزدها. گره

روش EXTEND () یک روش شیء لیست است که انتظار دارد که یک تکرار شود و مقادیر خود را به لیست اضافه کند.

معمولاً لیستی را به آن منتقل می کنیم:

اما در کد شما یک ژنراتور می شود ، که خوب است زیرا:

  1. نیازی به خواندن مقادیر دو بار نیست.
  2. شما ممکن است فرزندان زیادی داشته باشید و نمی خواهید همه آنها در حافظه ذخیره شوند.

و این کار می کند زیرا پایتون اهمیتی نمی دهد که آیا استدلال یک روش یک لیست است یا خیر. پایتون انتظار تکرار را دارد ، بنابراین با رشته ها ، لیست ها ، Tuples و ژنراتور کار خواهد کرد! به این تایپ کردن اردک گفته می شود و یکی از دلایلی است که پایتون بسیار خونسرد است. اما این یک داستان دیگر است ، برای یک سوال دیگر.

می توانید در اینجا متوقف شوید ، یا کمی بخوانید تا یک استفاده پیشرفته از ژنراتور را ببینید:

کنترل فرسودگی ژنراتور

توجه: برای Python 3 ، از چاپ (coer_street_atm . __ بعدی __ ()) یا چاپ (Next (coer_street_atm) استفاده کنید)

این می تواند برای موارد مختلف مانند کنترل دسترسی به یک منبع مفید باشد.

itertools ، بهترین دوست شما

ماژول ITERTOOLS شامل عملکردهای ویژه ای برای دستکاری در تکرار است. تا به حال مایل به کپی کردن یک ژنراتور هستید؟دو ژنراتور زنجیره ای؟مقادیر گروهی در یک لیست تو در تو با یک لاینر؟نقشه / زیپ بدون ایجاد لیست دیگری؟

سپس فقط itertools را وارد کنید.

یک مثال؟بیایید سفارشات احتمالی ورود برای یک مسابقه چهار اسب را ببینیم:

درک مکانیسم های درونی تکرار

تکرار فرایندی است که حاکی از تکرار (اجرای روش __iter __ ()) و تکرار سازها (اجرای روش __next __ ()) است. iterables هر اشیاء هستند که می توانید از آن استفاده کنید. تکرارها اشیاء هستند که به شما امکان می دهند تا از طریق تکرار تکرار شوید.

در این مقاله اطلاعات بیشتری در مورد چگونگی کار برای حلقه ها وجود دارد.

بازده آنقدر جادویی نیست که این پاسخ نشان می دهد. وقتی تابعی را صدا می کنید که حاوی بیانیه بازده در هر نقطه باشد ، یک شیء ژنراتور دریافت می کنید ، اما هیچ کد اجرا نمی شود. سپس هر بار که یک شی را از ژنراتور استخراج می کنید ، پایتون کد را در عملکرد اجرا می کند تا زمانی که به یک بیانیه بازده برسد ، سپس مکث کرده و شی را تحویل می دهد. هنگامی که شما یک شیء دیگر را استخراج می کنید ، پایتون درست پس از عملکرد از سر گرفته می شود و تا رسیدن به عملکرد دیگر (اغلب همان یک ، اما یک تکرار بعد) ادامه می یابد. این کار تا زمانی که عملکرد پایان یابد ادامه می یابد ، که در آن مرحله ژنراتور خسته به نظر می رسد.

"این تکرار کننده ها مفید هستند. اما شما تمام مقادیر موجود در حافظه را ذخیره می کنید و این همیشه چیزی نیست که شما می خواهید" ، اشتباه یا گیج کننده است. یک تکرار کننده با فراخوانی ITER () در مورد تکرار ، یک تکرار کننده را برمی گرداند و یک تکرار کننده همیشه بسته به اجرای روش ITER ، لازم نیست مقادیر خود را در حافظه ذخیره کند ، همچنین می تواند مقادیر موجود در دنباله را در صورت تقاضا ایجاد کند.

خوب است که به این جواب عالی اضافه کنیم که چرا به جای [] به جای [] استفاده می شود ، به طور خاص یکسان است ، به ویژه آنچه () است (ممکن است با یک تاپل سردرگمی وجود داشته باشد).

matthiasfripp "این ادامه می یابد تا زمانی که عملکرد پایان یابد" - یا با بیانیه بازگشت روبرو می شود.(بازگشت در یک تابع حاوی بازده مجاز است ، به شرط آنکه مقدار بازگشت را مشخص نکند.)

بیانیه بازده اجرای عملکرد را به حالت تعلیق در می آورد و مقدار را به تماس گیرنده ارسال می کند ، اما حالت کافی را حفظ می کند تا عملکرد را فعال کند تا جایی را که از آن خارج شده است ، از سر بگیرد. هنگام از سرگیری ، عملکرد بلافاصله پس از آخرین عملکرد عملکرد ادامه می یابد. این به کد آن اجازه می دهد تا به جای آنکه به طور همزمان آنها را محاسبه کرده و آنها را مانند یک لیست بازگرداند ، یک سری از مقادیر را با گذشت زمان تولید کند.

میانبر برای درک عملکرد

هنگامی که عملکردی با بیانیه های عملکرد را مشاهده می کنید ، این ترفند آسان را برای درک آنچه اتفاق خواهد افتاد ، اعمال کنید:

  1. در شروع عملکرد یک نتیجه خط = [] قرار دهید.
  2. هر بازده EXPR را با نتیجه. APPEND (EXPR) جایگزین کنید.
  3. نتیجه بازگشت خط را در پایین عملکرد وارد کنید.
  4. بله - دیگر اظهارات عملکردی! کد را بخوانید و بفهمید.
  5. عملکرد را با تعریف اصلی مقایسه کنید.

این ترفند ممکن است ایده ای از منطق پشت عملکرد به شما بدهد ، اما آنچه در واقع با عملکرد اتفاق می افتد متفاوت از آنچه در رویکرد مبتنی بر لیست اتفاق می افتد متفاوت است. در بسیاری از موارد ، رویکرد عملکرد بسیار کارآمدتر و سریعتر خواهد بود. در موارد دیگر ، این ترفند شما را در یک حلقه نامحدود گیر می کند ، حتی اگر عملکرد اصلی کاملاً خوب کار کند. برای یادگیری بیشتر بخوانید.

تکرار کننده ها ، تکرارها و ژنراتورها را اشتباه نگیرید

اول ، پروتکل iterator - وقتی می نویسید

پایتون دو مرحله زیر را انجام می دهد:

یک تکرار کننده برای myList می شود:

Call iter(mylist) >این یک شی را با یک روش بعدی () (یا __next __ () در پایتون 3) برمی گرداند.

[این گامی است که بیشتر مردم فراموش می کنند که به شما بگویند]

از تکرار برای حلقه های موارد استفاده می کند:

با استفاده از روش بعدی () در تکرار برگشت از مرحله 1 تماس بگیرید. مقدار بازگشت از بعدی () به X اختصاص داده می شود و بدنه حلقه اجرا می شود. اگر یک توقف استثناء از درون بعدی () مطرح شود ، به این معنی است که هیچ مقادیر بیشتری در تکرار وجود ندارد و حلقه خارج می شود.

حقیقت این است که پایتون دو مرحله فوق را در هر زمان که بخواهد بر روی محتوای یک شیء حلقه کند ، انجام می دهد - بنابراین می تواند یک حلقه باشد ، اما می تواند کدی مانند otherlist. extend (myList) باشد (جایی که لیست دیگر یک لیست پایتون است)بشر

در اینجا MyList یک تکرار است زیرا پروتکل تکرار را پیاده سازی می کند. در یک کلاس تعریف شده توسط کاربر ، می توانید روش __iter __ () را پیاده سازی کنید تا نمونه هایی از کلاس خود را قابل تکرار کنید. این روش باید یک تکرار کننده را برگرداند. تکرار کننده یک شی با روش بعدی () است. اجرای هر دو __iter __ () و Next () در همان کلاس امکان پذیر است و __iter __ () بازگشت به خود دارد. این برای موارد ساده کار خواهد کرد ، اما نه وقتی می خواهید دو تکرار در همان زمان بر روی یک شیء قرار بگیرند.

بنابراین این پروتکل تکرار کننده است ، بسیاری از اشیاء این پروتکل را پیاده سازی می کنند:

  1. لیست های داخلی ، فرهنگ لغت ، Tuples ، مجموعه ها و پرونده ها.
  2. کلاسهای تعریف شده توسط کاربر که __iter __ () را پیاده سازی می کنند.
  3. ژنراتورها

توجه داشته باشید که A برای حلقه نمی داند با چه نوع شیئی برخورد می کند - فقط پروتکل تکرار را دنبال می کند ، و خوشحال است که پس از کالای مورد نظر بعدی را دریافت می کند (). لیست های داخلی موارد خود را یک به یک برمی گردانند ، فرهنگ لغت کلیدها را یک به یک برمی گردانند ، پرونده ها خطوط را یک به یک و غیره برمی گردانند و ژنراتورها برمی گردند. خوب این جایی است که بازده وارد می شود:

به جای اظهارات بازده ، اگر سه بیانیه بازگشت در F123 () فقط اولین بار اجرا می شود و عملکرد از آن خارج می شود. اما F123 () عملکرد معمولی نیست. هنگامی که F123 () خوانده می شود ، هیچ یک از مقادیر موجود در اظهارات عملکرد را برنگرداند! این یک شیء ژنراتور را برمی گرداند. همچنین ، این عملکرد واقعاً از آن خارج نمی شود - به حالت معلق می رود. هنگامی که حلقه برای حلقه ژنراتور حلقه می کند ، عملکرد از حالت معلق آن در خط بعدی پس از بازدهی که قبلاً از آن بازگردانده شده است ، از سر می رود ، در این حالت خط بعدی کد را اجرا می کند ، و آن را باز می گرداند و آن را برمی گرداند. به عنوان مورد بعدیاین اتفاق تا زمانی که عملکرد خارج شود اتفاق می افتد ، در آن مرحله ژنراتور توقف را بالا می برد و حلقه از آن خارج می شود.

بنابراین شیء ژنراتور مانند یک آداپتور است - در یک انتها پروتکل تکرار ساز را با قرار دادن __iter __ () و بعد () () به نمایش می گذارد تا بتواند حلقه را خوشحال کند. در انتهای دیگر ، این عملکرد را به اندازه کافی اجرا می کند تا مقدار بعدی از آن خارج شود و آن را در حالت معلق قرار دهد.

چرا از ژنراتورها استفاده می کنیم؟

معمولاً می توانید کدی بنویسید که از ژنراتورها استفاده نمی کند اما همان منطق را پیاده سازی می کند. یک گزینه استفاده از لیست موقت "ترفند" است که قبلاً به آن اشاره کردم. که در همه موارد کار نمی کند ، به عنوان مثالاگر حلقه های نامتناهی دارید ، یا ممکن است در هنگام داشتن یک لیست واقعاً طولانی ، از حافظه ناکارآمد استفاده کند. رویکرد دیگر اجرای یک کلاس جدید تکرار پذیر است که دولت را در مثال اعضای خود نگه می دارد و مرحله منطقی بعدی را در روش بعدی () (یا __next __ () در پایتون 3) انجام می دهد. بسته به منطق ، کد موجود در روش بعدی () ممکن است به نظر برسد بسیار پیچیده و مستعد اشکالات باشد. در اینجا ژنراتورها یک راه حل تمیز و آسان ارائه می دهند.

"وقتی عملکردی با اظهارات عملکرد را مشاهده می کنید ، این ترفند آسان را برای درک آنچه اتفاق خواهد افتاد ، اعمال کنید" آیا این واقعیت را نادیده نمی گیرد که می توانید به یک ژنراتور ارسال کنید ، که بخش عظیمی از نقطه ژنراتورها است؟

"it could be a for loop, but it could also be code like otherlist.extend(mylist) " >این نادرست استگسترش () لیست را در محل اصلاح می کند و یک تکرار را بر نمی گرداند. تلاش برای حلقه زدن به لیست های دیگر

pedro شما آن جمله را اشتباه درک کرده اید. این بدان معنی است که پایتون هنگام اجرای OtherList. extend (MyList) دو مرحله ذکر شده را در MyList (نه در لیست دیگر) انجام می دهد.

به این روش فکر کنید:

تکرار کننده فقط یک اصطلاح صدا فانتزی برای یک شیء است که دارای یک روش بعدی () است. بنابراین یک عملکرد بازدهی به پایان می رسد چیزی شبیه به این:

این اساساً همان کاری است که مترجم پایتون با کد فوق انجام می دهد:

برای بینش بیشتر در مورد آنچه در پشت صحنه اتفاق می افتد ، حلقه برای این موضوع می تواند بازنویسی شود:

آیا این بیشتر حس می کند یا فقط شما را بیشتر گیج می کند؟:)

باید توجه داشته باشم که این یک توضیح بیش از حد برای اهداف مصور است.:)

__getItem__ می تواند به جای __iter__ تعریف شود. به عنوان مثال: کلاس IT: PASS ؛آن . __ getItem__ = lambda self ، i: i*10 اگر من<10 else [][0]; for i in it(): print(i) , It will print: 0, 10, 20, . 90

من این مثال را در Python 3. 6 امتحان کردم و اگر iterator = some_function () را ایجاد کنم ، تکرارگر متغیر دیگر تابعی به نام بعدی () ندارد ، بلکه فقط یک عملکرد __next __ () است. فکر می کردم به آن اشاره می کنم

از کجا اجرای حلقه ای که شما نوشتید با روش __iter__ iterator ، نمونه فوری آن تماس می گیرد؟

متأسفانه این پاسخ اصلاً درست نیست. این کاری نیست که مترجم پایتون با ژنراتورها انجام می دهد. این کلاس در حال ایجاد کلاس از عملکرد ژنراتور نیست و __iter__ و __next__ را پیاده سازی می کند. آنچه در زیر کاپوت انجام می شود در این پست stackoverflow.com/questions/45723893/… توضیح داده شده است. برای استناد به Raymond Hettinger "ژنراتورهای داخلی همانطور که در کلاس خالص پایتون شما نشان داده شده است ، اجرا نمی شوند. در عوض ، آنها بیشتر از همان منطق عملکردهای معمولی را به اشتراک می گذارند"

کلمه کلیدی عملکرد به دو واقعیت ساده کاهش می یابد:

  1. اگر کامپایلر کلمه کلیدی بازده را در هر نقطه درون یک تابع تشخیص دهد ، آن عملکرد دیگر از طریق بیانیه بازگشت باز می گردد. در عوض ، بلافاصله یک شیء تنبل "لیست در انتظار" به نام ژنراتور را برمی گرداند
  2. یک ژنراتور قابل تکرار است. قابل تکرار چیست؟این چیزی شبیه به یک لیست یا مجموعه یا محدوده یا دیکته است ، با یک پروتکل داخلی برای بازدید از هر عنصر به ترتیب خاص.

به طور خلاصه: به طور معمول ، یک ژنراتور یک لیست تنبل و در انتظار افزایشی است و اظهارات عملکردی به شما امکان می دهد تا از نماد عملکرد برای برنامه ریزی مقادیر لیست استفاده کنید که ژنراتور باید به صورت تدریجی از بین برود. علاوه بر این ، استفاده پیشرفته به شما امکان می دهد از ژنراتور به عنوان Coroutines استفاده کنید (به تصویر زیر مراجعه کنید).

اساساً ، هر زمان که بیانیه عملکرد با آن روبرو شود ، عملکرد مکث و ذخیره می کند ، سپس "مقدار بازگشت بعدی در" لیست "را مطابق پروتکل تکرار پیتون (به برخی از ساختارهای نحوی مانند یک حلقه برای حلقه ای که به طور مکرر در آینده تماس می گیرد ، منتشر می کند.() و یک استثناء توقف ، و غیره). ممکن است با ژنراتور با بیان ژنراتور روبرو شوید. توابع ژنراتور قدرتمندتر هستند زیرا می توانید آرگومان ها را به عملکرد ژنراتور مکث منتقل کنید و از آنها برای اجرای Coroutines استفاده کنید. بعداً در مورد آن

مثال اساسی ("لیست")

بیایید یک عملکرد MakerAnge را دقیقاً مانند دامنه پایتون تعریف کنیم. تماس Makerange (N) یک ژنراتور را برمی گرداند:

برای مجبور کردن ژنراتور برای بازگشت بلافاصله مقادیر در حال تعلیق ، می توانید آن را به لیست () منتقل کنید (دقیقاً مثل هر نوع قابل تکرار):

مقایسه مثال با "فقط بازگشت یک لیست"

مثال فوق را می توان به عنوان صرفاً ایجاد لیستی که به آن اضافه می کنید و بازگردید ، تصور کرد:

یک تفاوت عمده وجود دارد ، هر چند ؛بخش آخر را ببینید.

چگونه ممکن است از ژنراتورها استفاده کنید

قابل تکرار آخرین قسمت از درک لیست است و همه ژنراتورها قابل تکرار هستند ، بنابراین اغلب از آنها استفاده می شود:

برای به دست آوردن احساس بهتر برای ژنراتورها ، می توانید با ماژول IterTools بازی کنید (حتماً از زنجیره ای استفاده کنید. از طریق زنجیره ای به جای زنجیره ای در صورت لزوم). به عنوان مثال ، شما حتی ممکن است از ژنراتورها برای اجرای لیست های تنبل بی نهایت طولانی مانند itertools.count () استفاده کنید. شما می توانید def enumerate خود را (قابل تکرار) (zip (شمارش () ، قابل تکرار) پیاده سازی کنید ، یا در عوض این کار را با کلمه کلیدی عملکرد در یک حلقه مدتی انجام دهید.

لطفاً توجه داشته باشید: ژنراتورها در واقع می توانند برای بسیاری از موارد دیگر ، مانند اجرای Coroutines یا برنامه نویسی غیر تعیین کننده یا سایر موارد ظریف استفاده شوند. با این حال ، دیدگاه "لیست های تنبل" که من در اینجا ارائه می دهم رایج ترین استفاده ای است که شما پیدا خواهید کرد.

پشت صحنه

اینگونه است که "پروتکل تکرار پایتون" کار می کند. یعنی آنچه در هنگام انجام لیست اتفاق می افتد (Makerange (5)). این همان چیزی است که من قبلاً به عنوان "لیست تنبل و افزایشی" توصیف می کنم.

تابع داخلی بعدی () فقط اشیاء را فراخوانی می کند . __ بعدی __ () ، که بخشی از "پروتکل تکرار" است و در تمام تکرارها یافت می شود. شما می توانید به صورت دستی از عملکرد بعدی () (و سایر قسمت های پروتکل تکرار) برای اجرای موارد فانتزی ، معمولاً با هزینه خوانایی استفاده کنید ، بنابراین سعی کنید از انجام این کار خودداری کنید.

قیافه

Coroutine (ژنراتورهایی که به طور کلی ورودی را از طریق کلمه کلیدی عملکرد می پذیرند ، به عنوان مثال NextInput = عملکرد بعدی ، به عنوان نوعی ارتباط دو طرفه) اساساً محاسباتی است که مجاز به مکث خود و درخواست ورودی است (به عنوان مثال آنچه باید در آینده انجام دهد). هنگامی که Coroutine خود را مکث می کند (هنگامی که Coroutine در حال اجرا در نهایت به یک کلمه کلیدی بازده برخورد می کند) ، محاسبه متوقف می شود و کنترل معکوس می شود (به دست می آید) به عملکرد "فراخوانی" (قاب که مقدار بعدی محاسبه را درخواست می کند) باز می گردد. ژنراتور مکث/Coroutine متوقف می شود تا زمانی که یکی دیگر از عملکردهای فراخوانی (احتمالاً یک عملکرد/متن متفاوت) مقدار بعدی را برای عدم تمایل به آن درخواست کند (معمولاً داده های ورودی را برای هدایت فضای داخلی مکث به کد Coroutine منتقل می کند).

شما می توانید از Coroutines Python به عنوان لیست های در حال افزایش به صورت تنبل فکر کنید ، جایی که عنصر بعدی فقط به محاسبات قبلی بستگی ندارد ، بلکه به ورودی نیز می توانید در طی فرآیند تولید تزریق کنید.

جبهه

به طور معمول ، بیشتر افراد به تمایزات زیر اهمیت نمی دهند و احتمالاً می خواهند جلوی خواندن در اینجا را بگیرند.

در Python-Speak ، یکدولر هر شیئی است که "مفهوم حلقه for" را مانند یک لیست درک می کند [1،2،3] ، و یک تکرار کننده نمونه خاصی از درخواست شده برای حلقه مانند [1،2 است، 3] . __ iter __ (). یک ژنراتور دقیقاً همانند هر تکرار کننده است ، به جز روشی که نوشته شده است (با نحو عملکرد).

هنگامی که از یک لیست تکرار می کنید ، یک تکرار جدید ایجاد می کند. با این حال ، هنگامی که شما یک تکرار کننده را از یک تکرار کننده (که به ندرت انجام می دهید) درخواست می کنید ، فقط یک نسخه از خود را به شما می دهد.

بنابراین ، در صورت بعید است که شما نتوانید کاری از این دست انجام دهید.

بشرسپس به یاد داشته باشید که یک ژنراتور یک تکرار کننده است. یعنی یک بار کاربردی است. اگر می خواهید از آن استفاده مجدد کنید ، باید دوباره با MyRange (.) تماس بگیرید. اگر نیاز به دو بار از نتیجه دارید ، نتیجه را به لیست تبدیل کرده و آن را در یک متغیر x = لیست (myRange (5)) ذخیره کنید. کسانی که کاملاً نیاز به کلون کردن یک ژنراتور دارند (به عنوان مثال ، که در حال انجام استعاره های هکری وحشتناک هستند) می توانند از itertools. tee استفاده کنند (هنوز هم در پایتون 3 کار می کند) در صورت لزوم ، از آنجا که پیشنهاد کپی می کند پیشنهادات استاندارد Python Pep به تعویق افتاده است.

کلمه کلیدی عملکرد در پایتون چه کاری انجام می دهد؟

پاسخ طرح/خلاصه

  • تابعی با عملکرد ، در صورت فراخوانی ، ژنراتور را برمی گرداند.
  • ژنراتورها تکرار کننده هستند زیرا پروتکل تکرار را اجرا می کنند ، بنابراین می توانید بر روی آنها تکرار کنید.
  • یک ژنراتور همچنین می تواند اطلاعاتی ارسال شود ، و آن را از نظر مفهومی به یک Coroutine تبدیل می کند.
  • در پایتون 3 ، می توانید از یک ژنراتور به دیگری در هر دو جهت با بازده از آن نمایندگی کنید.
  • (پیوست چند پاسخ ، از جمله بالا ، انتقاد می کند و در مورد استفاده از بازگشت در یک ژنراتور بحث می کند.)

ژنراتورها:

عملکرد فقط در یک تعریف عملکرد قانونی است و گنجاندن عملکرد در یک تعریف عملکرد باعث می شود که یک ژنراتور را برگرداند.

ایده ژنراتورها از زبانهای دیگر (به پاورقی 1 مراجعه کنید) با پیاده سازی های مختلف ارائه می شود. در ژنراتورهای پایتون ، اجرای کد در نقطه عملکرد منجمد می شود. هنگامی که ژنراتور خوانده می شود (روشها در زیر مورد بحث قرار می گیرد) اجرای از سر گرفته می شود و سپس در عملکرد بعدی یخ می زند.

عملکرد یک روش آسان برای اجرای پروتکل iterator ، تعریف شده توسط دو روش زیر است: __iter__ و __next__. هر دو روش ، یک شیء را به یک تکرار کننده تبدیل می کنند که می توانید با کلاس پایه انتزاعی تکرار شده از ماژول مجموعه ها نوع بررسی کنید.

بیایید مقداری درون نگری انجام دهیم:

نوع ژنراتور زیر نوع تکرار است:

و در صورت لزوم ، ما می توانیم مانند این نوع بررسی کنیم:

یکی از ویژگی های یک تکرار کننده این است که پس از خسته شدن ، شما نمی توانید از آن استفاده مجدد یا تنظیم مجدد کنید:

اگر می خواهید دوباره از عملکرد آن استفاده کنید ، باید دیگری را بسازید (به پاورقی 2 مراجعه کنید):

به عنوان مثال می توان داده ها را به صورت برنامه ای به دست آورد:

ژنراتور ساده فوق نیز معادل موارد زیر است - از Python 3. 3 شما می توانید از بازده استفاده کنید:

با این حال ، عملکرد از این امکان را برای نمایندگان به نمایندگان می دهد ، که در بخش زیر در مورد نمایندگی تعاونی با زیرزمین های فرعی توضیح داده خواهد شد.

Coroutines:

بازده عبارتی را تشکیل می دهد که اجازه می دهد داده ها به ژنراتور ارسال شوند (به پاورقی 3 مراجعه کنید)

در اینجا مثالی وجود دارد ، به متغیر دریافت شده توجه داشته باشید ، که به داده هایی که به ژنراتور ارسال می شود اشاره می کند:

ابتدا باید ژنراتور را با عملکرد Builtin ، در مرحله بعدی قرار دهیم. بسته به نسخه پایتون که از آن استفاده می کنید ، روش بعدی یا __next__ مناسب را فراخوانی می کند:

و اکنون می توانیم داده ها را به ژنراتور ارسال کنیم.(ارسال هیچکدام با تماس بعدی نیست.):

هیئت تعاونی به زیر کرروتین با عملکرد از

اکنون ، به یاد بیاورید که بازده از آن در پایتون 3 موجود است. این به ما امکان می دهد تا Coroutines را به یک زیر قوطی واگذار کنیم:

و اکنون ما می توانیم عملکرد را به یک ژنراتور فرعی واگذار کنیم و می توان از آن توسط یک ژنراتور درست مانند بالا استفاده کرد:

اکنون اضافه کردن اضافه کردن 1000 نفر دیگر به حساب به علاوه بازده حساب (60. 0):

می توانید اطلاعات بیشتر در مورد معنایی دقیق عملکرد از PEP 380 بخوانید.

روشهای دیگر: بستن و پرتاب

روش نزدیک GeneratoreXit را در نقطه ای که اجرای عملکرد منجمد شده است ، ایجاد می کند. این نیز توسط __del__ خوانده می شود ، بنابراین می توانید هر کد پاکسازی را در جایی که Generatorexit را اداره می کنید قرار دهید:

همچنین می توانید یک استثنا را که می تواند در ژنراتور انجام شود یا به کاربر پخش شود ، پرتاب کنید:

نتیجه

من معتقدم که من تمام جنبه های سوال زیر را پوشش داده ام:

کلمه کلیدی عملکرد در پایتون چه کاری انجام می دهد؟

به نظر می رسد که بازده کارهای زیادی انجام می دهد. من مطمئن هستم که می توانم نمونه های دقیق تری به این موضوع اضافه کنم. اگر بیشتر می خواهید یا انتقاد سازنده ای دارید ، با اظهار نظر در زیر به من اطلاع دهید.

ضمیمه:

انتقاد از پاسخ برتر/پذیرفته شده **

  • این در مورد آنچه که قابل تکرار است ، فقط با استفاده از یک لیست به عنوان نمونه اشتباه گرفته می شود. به منابع من در بالا مراجعه کنید ، اما به طور خلاصه: یک تکرار شده یک روش __iter__ دارد که یک تکرار را برمی گرداند. یک تکرار کننده علاوه بر این ، روش . __ بعدی را ارائه می دهد ، که به طور ضمنی برای حلقه ها توسط حلقه ها فراخوانی می شود تا اینکه توقف را افزایش دهد ، و پس از افزایش توقف ، این کار را ادامه خواهد داد.
  • سپس از یک عبارت ژنراتور برای توصیف ژنراتور استفاده می کند. از آنجا که یک بیان ژنراتور به سادگی یک روش مناسب برای ایجاد یک تکرار کننده است ، فقط موضوع را گیج می کند ، و ما هنوز به بخش عملکرد نرسیده ایم.
  • در کنترل فرسودگی ژنراتور ، او روش . next (که فقط در پایتون 2 کار می کند) می نامد ، در عوض او باید از عملکرد ساخته شده استفاده کند ، در مرحله بعد. تماس با Next (OBJ) یک لایه مناسب از Indirection خواهد بود ، زیرا کد وی در پایتون 3 کار نمی کند.
  • itertools؟این به آنچه عملکرد انجام می دهد ربطی نداشت.
  • هیچ بحثی در مورد روش هایی که عملکرد ارائه می دهد همراه با عملکرد جدید عملکرد از پایتون 3 نیست.

پاسخ برتر/پذیرفته شده یک پاسخ بسیار ناقص است.

انتقاد از پاسخ نشان دهنده عملکرد در یک بیان یا درک ژنراتور.

گرامر در حال حاضر اجازه می دهد هرگونه بیان در یک لیست درک لیست باشد.

از آنجا که عملکرد یک عبارت است ، توسط برخی جالب توجه به استفاده از آن در درک مطلب یا بیان ژنراتور - علیرغم استناد به هیچ موردی مناسب ، جالب توجه است.

توسعه دهندگان اصلی CPYTHON در حال بحث در مورد کاهش کمک هزینه آن هستند. در اینجا یک پست مربوطه از لیست پستی وجود دارد:

در 30 ژانویه 2017 در 19:05 ، برت کان نوشت:

در خورشید ، 29 ژانویه 2017 در 16:39 کریگ رودریگز نوشت:

من با هر دو رویکرد خوب هستم. IMHO ، ترک چیزها به روشی که در پایتون 3 وجود دارد ، خوب نیست.

رأی من این است که این یک synterror باشد زیرا شما آنچه را که از نحو انتظار دارید دریافت نمی کنید.

من موافقم که این یک مکان معقول برای به پایان رساندن ما است ، زیرا هر کدی با تکیه بر رفتار فعلی واقعاً بسیار باهوش است که قابل حفظ باشد.

از نظر رسیدن به آنجا ، ما احتمالاً می خواهیم:

  • سد نحوی یا استهلاک در 3. 7
  • هشدار py3k در 2. 7. x
  • syntaxerror در 3. 8

- نیک کوگلان |ncoghlan در gmail.com |بریزبن ، استرالیا

علاوه بر این ، یک مسئله برجسته (10544) وجود دارد که به نظر می رسد در جهت این امر هرگز ایده خوبی نیست (پیپی ، اجرای پایتون که در پایتون نوشته شده است ، در حال حاضر هشدارهای نحوی را افزایش می دهد.)

خط پایین ، تا زمانی که توسعه دهندگان Cpython به ما بگویند در غیر این صورت: عملکرد را در یک بیان یا درک ژنراتور قرار ندهید.

بیانیه بازگشت در یک ژنراتور

در یک عملکرد ژنراتور ، عبارت بازگشت نشان می دهد که ژنراتور انجام شده و باعث افزایش توقف می شود. مقدار برگشتی (در صورت وجود) به عنوان آرگومان برای ساخت توقف استفاده می شود و به ویژگی Stopiteration. Value تبدیل می شود.

نکته تاریخی ، در پایتون 2: "در یک عملکرد ژنراتور ، بیانیه بازگشت مجاز به شامل یک بیان_ لیست نیست. در این زمینه ، بازگشت برهنه نشان می دهد که ژنراتور انجام شده و باعث افزایش توقف می شود."یک Expression_List اساساً هر تعداد عبارات جدا شده توسط کاما است - در واقع ، در پایتون 2 ، می توانید ژنراتور را با بازگشت متوقف کنید ، اما نمی توانید یک مقدار را برگردانید.

پانویسها و منابع

به زبانهای CLU ، Sather و Icon در پیشنهاد معرفی مفهوم ژنراتورها به پایتون اشاره شد. ایده کلی این است که یک تابع می تواند وضعیت داخلی را حفظ کرده و نقاط داده واسطه ای را در صورت تقاضا توسط کاربر داشته باشد. این قول داده شده است که از نظر سایر رویکردها ، از جمله نخ پایتون ، برتر باشد ، که حتی در برخی از سیستم ها نیز در دسترس نیست.

به عنوان مثال ، این بدان معناست که اشیاء دامنه تکراری نیستند ، حتی اگر قابل تکرار باشند ، زیرا می توان از آنها استفاده مجدد کرد. مانند لیست ها ، روش های __iter__ آنها اشیاء Iterator را برمی گرداند.

بازده در ابتدا به عنوان بیانیه معرفی شد ، به این معنی که فقط می تواند در ابتدای یک خط در یک بلوک کد ظاهر شود. اکنون عملکرد یک بیان عملکرد ایجاد می کند. https://docs. python.org/2/reference/simple_stmts.html#grammar-token-yield_stmt این تغییر پیشنهاد شده است تا کاربر بتواند درست همانطور که ممکن است آن را به ژنراتور ارسال کند. برای ارسال داده ، باید بتواند آن را به چیزی اختصاص دهد ، و برای آن ، بیانیه ای کار نمی کند.

عملکرد دقیقاً مانند بازگشت است - هر آنچه را که به آن می گویید برمی گردد (به عنوان ژنراتور). تفاوت این است که دفعه بعد که با ژنراتور تماس می گیرید ، اجرای از آخرین تماس به بیانیه عملکرد شروع می شود. بر خلاف بازگشت ، قاب پشته هنگام بروز عملکرد تمیز نمی شود ، اما کنترل به تماس گیرنده منتقل می شود ، بنابراین دفعه بعد که عملکرد نامیده می شود ، حالت آن از سر می گیرد.

در مورد کد شما ، عملکرد get_child_candidates مانند یک تکرار کننده عمل می کند به طوری که وقتی لیست خود را گسترش می دهید ، یک عنصر را همزمان به لیست جدید اضافه می کند.

List. extend تا زمانی که خسته نشود ، یک تکرار کننده را صدا می کند. در مورد نمونه کدی که ارسال کرده اید ، بسیار واضح تر است که فقط یک Tuple را برگردانید و آن را به لیست اضافه کنید.

این نزدیک است ، اما صحیح نیست. هر بار که با یک بیانیه با بیانیه عملکرد در آن تماس می گیرید ، یک شیء تولید کننده جدید را برمی گرداند. این تنها زمانی است که شما با روش . next () آن ژنراتور تماس می گیرید که اجرای آن پس از آخرین عملکرد از سر گرفته می شود.

یک چیز اضافی برای ذکر وجود دارد: تابعی که بازده در واقع لازم نیست خاتمه یابد. من کد مانند این را نوشتم:

سپس می توانم از آن در کد دیگری مانند این استفاده کنم:

این واقعاً به ساده کردن برخی از مشکلات کمک می کند و کار با آنها را آسان تر می کند.

برای کسانی که یک مثال حداقل کار را ترجیح می دهند ، در این جلسه تعاملی پایتون مراقبه کنید:

TL ؛ دکتر

به جای این:

این کار را انجام دهید:

هر زمان که خود را در حال ساخت لیستی از ابتدا هستید ، به جای آن ، هر قطعه را به دست می آورید.

این اولین لحظه "آه" من با عملکرد بود.

عملکرد یک روش شیرین برای گفتن است

عملکرد تک پاس است: شما فقط می توانید یک بار تکرار کنید. هنگامی که یک عملکرد در آن عملکرد دارد ، ما آن را یک عملکرد ژنراتور می نامیم. و یک تکرار کننده همان چیزی است که برمی گردد. این اصطلاحات آشکار است. ما راحتی یک ظرف را از دست می دهیم ، اما قدرت یک سری را که در صورت لزوم محاسبه می شود ، و به طور خودسرانه طولانی به دست می آوریم.

عملکرد تنبل است ، محاسبه را خاموش می کند. عملکردی با عملکرد در آن هنگام تماس با آن اصلاً اجرا نمی شود. این یک شیء تکرار شونده را برمی گرداند که به یاد می آورد که در آن جای خود را ترک کرده است. هر بار که با بعدی () در تکرار تماس می گیرید (این اتفاق در یک حلقه برای حلقه اتفاق می افتد) اینچ به جلو به بازده بعدی می رسد. بازگشت باعث افزایش توقف می شود و سریال را به پایان می رساند (این پایان طبیعی یک حلقه برای حلقه است).

عملکرد همه کاره است. داده ها لازم نیست که همه در کنار هم ذخیره شوند ، می توان آن را یک بار در دسترس قرار داد. می تواند بی نهایت باشد.

اگر به چندین پاس نیاز دارید و سریال خیلی طولانی نیست ، فقط لیست () را در آن تماس بگیرید:

انتخاب درخشان کلمه عملکرد زیرا هر دو معنی اعمال می شود:

عملکرد - تولید یا تأمین (مانند کشاورزی)

بشرداده های بعدی را در این سری ارائه دهید.

بازده - راه یا انصراف دهید (مانند قدرت سیاسی)

بشراجرای CPU را تا زمانی که تکرار شود ، کنار بگذارید.

عملکرد به شما ژنراتور می دهد.

همانطور که مشاهده می کنید ، در حالت اول Foo کل لیست را به طور همزمان در حافظه نگه می دارد. این یک لیست بزرگ برای لیست با 5 عنصر نیست ، اما اگر لیستی از 5 میلیون نفر را می خواهید ، چه می کنید؟این نه تنها یک غذای بزرگ حافظه است ، بلکه برای ساخت آن در زمانی که این عملکرد نامیده می شود ، زمان زیادی نیز هزینه دارد.

در مورد دوم ، بار فقط به شما ژنراتور می دهد. یک ژنراتور یک تکرار پذیر است-این بدان معنی است که می توانید از آن در یک حلقه و غیره استفاده کنید ، اما به هر مقدار فقط یک بار قابل دسترسی است. تمام مقادیر نیز به طور همزمان در حافظه ذخیره نمی شوند. شیء ژنراتور "به یاد می آورد" جایی که آخرین باری که آن را صدا می کنید در حلقه بود-به این ترتیب ، اگر از یک تکرار برای (مثلاً) به 50 میلیارد حساب کنید ، لازم نیست که 50 میلیارد حساب کنیدبه یکباره و 50 میلیارد شماره را برای حساب کردن ذخیره کنید.

باز هم ، این یک نمونه بسیار مهم است ، اگر واقعاً می خواستید 50 میلیارد حساب کنید ، احتمالاً از itertools استفاده می کنید.:)

این ساده ترین مورد استفاده از ژنراتورها است. همانطور که گفتید ، می توان از آن برای نوشتن مجوزهای کارآمد استفاده کرد ، با استفاده از عملکرد برای فشار آوردن به جای استفاده از نوعی متغیر پشته ، از طریق پشته تماس بالا می رود. ژنراتورها همچنین می توانند برای گذرگاه تخصصی درخت و همه نوع چیزهای دیگر مورد استفاده قرار گیرند.

فقط یک یادداشت - در Python 3 ، دامنه همچنین یک ژنراتور را به جای یک لیست باز می گرداند ، بنابراین شما همچنین می خواهید یک ایده مشابه را ببینید ، به جز اینکه __repr__ / __str__ برای نشان دادن نتیجه بهتر ، در این محدوده مورد (1 ، 10 ، نادیده گرفته می شود (1 ، 10 ،2)

در حال بازگشت یک ژنراتور است. من به خصوص با پایتون آشنا نیستم ، اما معتقدم اگر با آنها آشنا باشید ، همان نوع بلوک های تکراری C#است.

ایده اصلی این است که کامپایلر/مترجم/هر کاری که برخی از ترفندها را انجام می دهد ، به طوری که تا آنجا که به تماس گیرنده مربوط می شود ، آنها می توانند با تماس بعدی () تماس بگیرند و مقادیر بازگرداندن را ادامه دهند - گویی که روش ژنراتور متوقف شده است. اکنون بدیهی است که شما واقعاً نمی توانید یک روش "مکث" کنید ، بنابراین کامپایلر یک دستگاه دولتی را برای شما ایجاد می کند تا به خاطر داشته باشید که در حال حاضر کجا هستید و متغیرهای محلی و غیره به چه شکلی هستند. این بسیار ساده تر از نوشتن یک تکرار کننده خودتان است.

یک نوع پاسخ وجود دارد که من احساس نمی کنم هنوز به آنها داده شده است ، در میان بسیاری از پاسخ های عالی که نحوه استفاده از ژنراتورها را توصیف می کند. در اینجا پاسخ تئوری زبان برنامه نویسی است:

بیانیه عملکرد در پایتون یک ژنراتور را برمی گرداند. یک ژنراتور در پایتون تابعی است که ادامه می دهد (و به طور خاص یک نوع Coroutine ، اما ادامه ها مکانیسم کلی تر برای درک آنچه اتفاق می افتد را نشان می دهد).

ادامه در تئوری زبانهای برنامه نویسی یک نوع محاسبات بسیار اساسی تر است ، اما اغلب از آنها استفاده نمی شود ، زیرا استدلال در مورد آنها بسیار سخت است و همچنین اجرای آن بسیار دشوار است. اما ایده این که یک ادامه چیست ، ساده است: این وضعیت محاسباتی است که هنوز تمام نشده است. در این حالت ، مقادیر فعلی متغیرها ، عملیاتی که هنوز انجام نشده است و غیره ذخیره می شوند. سپس در مقطعی بعد از برنامه ، ادامه می توان از ادامه استفاده کرد ، به گونه ای که متغیرهای برنامه به آن حالت بازنشانی می شوند و عملیات ذخیره شده انجام می شود.

ادامه ، به این شکل کلی تر ، از دو طریق قابل اجرا است. در راه Call/CC ، پشته برنامه به معنای واقعی کلمه ذخیره می شود و پس از ادامه ادامه ، پشته بازیابی می شود.

در ادامه سبک عبور (CPS) ، ادامه کار فقط توابع عادی (فقط در زبانهایی است که توابع کلاس اول هستند) که برنامه نویس صریحاً مدیریت می کند و به زیر مجموعه ها منتقل می شود. در این سبک ، وضعیت برنامه با تعطیلی (و متغیرهایی که در آنها رمزگذاری می شود) نشان داده می شود تا متغیرهایی که در جایی در پشته زندگی می کنند. کارکردهایی که جریان کنترل را مدیریت می کنند ، ادامه را به عنوان آرگومان (در برخی از تغییرات CPS ، توابع ممکن است مداوم را بپذیرد) و با فراخوانی آنها با فراخوانی آنها و بازگشت پس از آن ، جریان کنترل را دستکاری می کنند. یک نمونه بسیار ساده از سبک عبور ادامه به شرح زیر است:

در این مثال (بسیار ساده گرا) ، برنامه نویس عملکرد نوشتن پرونده را در یک ادامه ذخیره می کند (که به طور بالقوه می تواند یک عمل بسیار پیچیده با جزئیات بسیاری برای نوشتن باشد) ، و سپس آن را ادامه می دهد (یعنی به عنوان اول-بسته شدن کلاس) به یک اپراتور دیگر که پردازش بیشتری انجام می دهد ، و سپس در صورت لزوم آن را صدا می کند..

بقیه این پست ، بدون از دست دادن کلی ، مفهوم سازی را به عنوان CPS مفهوم سازی می کند ، زیرا این یک جهنم بسیار ساده تر است و خواندن.

حال بیایید در مورد ژنراتورها در پایتون صحبت کنیم. ژنراتورها یک زیرگروه خاص از ادامه هستند. در حالی که استمرار به طور کلی قادر به ذخیره وضعیت محاسبات (یعنی پشته تماس برنامه) است ، ژنراتورها فقط قادر به ذخیره وضعیت تکرار در یک تکرار هستند. اگرچه ، این تعریف برای موارد استفاده خاصی از ژنراتورها کمی گمراه کننده است. برای مثال:

این به وضوح یک تکرار منطقی است که رفتار آن به خوبی تعریف شده است - هر بار که ژنراتور بر روی آن تکرار می شود ، 4 را برمی گرداند (و این کار را برای همیشه انجام می دهد). اما احتمالاً این نوع نمونه اولیه قابل تکرار نیست که هنگام فکر کردن به تکرارها به ذهن خطور می کند (یعنی برای X در مجموعه: do_something (x)). این مثال قدرت ژنراتورها را نشان می دهد: اگر چیزی تکرار شونده باشد ، یک ژنراتور می تواند وضعیت تکرار آن را نجات دهد.

برای تکرار مجدد: ادامه می تواند وضعیت پشته یک برنامه را نجات دهد و ژنراتورها می توانند وضعیت تکرار را نجات دهند. این بدان معنی است که ادامه ها بسیار قدرتمندتر از ژنراتورها هستند ، اما همچنین ژنراتورها بسیار ساده تر هستند. اجرای آنها برای طراح زبان ساده تر است و استفاده از برنامه نویس آسان تر است (اگر مدتی برای سوزاندن دارید ، سعی کنید این صفحه را در مورد ادامه و تماس/CC بخوانید و درک کنید).

اما شما به راحتی می توانید ژنراتورها را به عنوان یک مورد ساده و خاص از سبک گذر ادامه دهید (و مفهوم سازی کنید):

هر زمان که بازده فراخوانی شود ، به عملکرد می گوید که یک ادامه را بازگرداند. هنگامی که این تابع دوباره فراخوانی می شود ، از هر کجا که خارج شود شروع می شود. بنابراین ، در شبه Pseudocode (به عنوان مثال ، نه شبه کد ، اما نه کد) روش بعدی ژنراتور اساساً به شرح زیر است:

جایی که کلمه کلیدی عملکرد در واقع قند نحوی برای عملکرد ژنراتور واقعی است ، اساساً چیزی مانند:

به یاد داشته باشید که این فقط شبه کد است و اجرای واقعی ژنراتورها در پایتون پیچیده تر است. اما به عنوان یک تمرین برای درک آنچه اتفاق می افتد ، سعی کنید از سبک عبور مداوم برای اجرای اشیاء ژنراتور بدون استفاده از کلمه کلیدی عملکرد استفاده کنید.

فارکس وکسب درامد...
ما را در سایت فارکس وکسب درامد دنبال می کنید

برچسب : نویسنده : احمد قانع پور بازدید : 38 تاريخ : شنبه 3 تير 1402 ساعت: 11:42