<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های علی عابدی</title><link>https://virgool.ir/feed/@madensit</link><description>دانشجوی ارشد هوش مصنوعی، برنامه نویس. غرق در کامپیوتر، هوش مصنوعی، تکنولوژی و از این قبیل موضوعات.</description><language>fa</language><pubDate>2026-11-11 05:01:56</pubDate><image><url>https://files.virgool.ir/upload/users/1420/avatar/WxyFHY.png</url><title>علی عابدی</title><link>https://virgool.ir/@madensit</link></image><item><title>مفاهیمی در پایتون که شاید نمیدانید - بخش دوم - Generators</title><link>https://virgool.ir/@madensit/مفاهیمی-در-پایتون-که-شاید-نمیدانید-بخش-دوم-generators-e1znb6l0br2m</link><description>مقدمهبه دومین بخش از مجموعه‌ی مفاهیمی در پایتون که شاید نمیدانید خوش آمدید. اگر بخش اول را هنوز مطالعه نکرده‌اید میتوانید از طریق لینک زیر مقاله قبلی را مطالعه کنید. بخش اول پیش نیاز این بخش است.مفاهیمی در پایتون که شاید نمیدانید - بخش اول - Iteratorsدر این سری از نوشته‌ها، میخواهم به مفاهیمی در زبان برنامه‌نویسی پایتون بپردازم که شاید کمتر مورد توجه قرار گرفته باشد. امیداوارم این سری از مطالب برای افرادی که تازه شروع به یادگیری پایتون کرده‌اند و یا در میانه راه قرار دارند مفید باشد. این مطالب از این یک منبع خاص نیست. اما سعی میکنیم در طول نوشته، منابعی که به آنها رجوع کرده‌ام را بیان کنم.بخش دوم - Generatorsمقدمه - Generator چیست؟در مقاله بخش اول با مفهوم Iterator در پایتون آشنا شدیم. واسه اینکه بتونیم مفهوم generator را توضیح بدیم، یه برگشت به مقاله قبلی میزنیم. آخر مقاله قبلی نوشتم که &#34;شما خودتون هم میتونید iteratorهایی ایجاد کنید. کلاسی ایجاد کنید که متدهای __()iter__ و __()next__ را دارند و به همین راحتی iterator خودتون را ایجاد کنید.&#34; بیا یکم بیشتر در این باره حرف بزنیم.همونطور که گفتیم برای ایجاد یک Iterator باید یک کلاس ایجاد کنیم و دو تا متد __()iter__ و __()next__ را داخلش پیاده سازی کنیم. به این مثال دقت کن:نمونه‌ای از پیاده سازی دستی یک Iteratorدر کد بسیار ساده بالا یک کلاس به نام Test ایجاد کردیم و دو متد  __()iter__ و __()next__  را در اون پیاده سازی کردیم. در حقیقت کاری که این Iterator برای ما انجام میده اینه که هر بار یک عدد به قبلی اضافه میکنه و تا بی نهایت میتونیم ازش عدد بگیریم. خروجی کد بالا میشه:1&#xA;2&#xA;3&#xA;4اما این کار سخته؟ مگه نه؟ اگه قرار باشه برای هر Iterator که بخوایم ایجاد کنیم یه همچین کاری کنیم، عملا کسی سراغ استفاده از این قابلیت به صورت دستی نمیره. اینجاست که مفهوم Generator وارد بازی میشه!اگه بخوایم Generator را تعریف کنیم، می‌تونیم بگیم یک فانکشن هست که یک Iterator Object را برای ما برمیگردونه. در نتیجه با استفاده از اون میتونیم یک شی بگیریم که میشه روش تکرار (Iteration) انجام داد.حالا سوالی که پیش میاد اینه که چطوری می‌تونیم Generator ایجاد کنیم؟ به طور کلی، دور روش برای ایجاد Generator وجود داره. چگونه Generator ایجاد کنیم؟روش اول استفاده از yield توی فانکشن به جای return هست.نکته خیلی مهم تفاوت yield و return هست. وقتی ما return انجام می‌دیم، دستورات بعد از return دیگه اجرا نمیشن چون که کنترل برنامه به طور کامل به جایی میره که فانکشن‌ ما صدا زده شده و اگر دوباره همون فانکشن صدا زده بشه، دوباره از اول اجرا میشه. توی دستور yield وقتی که فانکشن‌ ما میرسه به این دستور، کنترل برنامه به دست جایی که صدا زده شده داده میشه، تا اینجا شبیه به return هست، اما اگر دوباره برنامه ما همون فانکشن‌ را صدا بزنه (البته با شرایطی که جلوتر توضیح میدم)، از ادامه جایی که آخرین yield بوده فانکشن‌ شروع به اجرا شدن می‌کنه و متغیرهایی که توی اون فانکشن تغییر دادیم آخرین مقدارشون (نه مقدار اولیه) را دارن. یک مقدار این مفهوم گیج کنندست اول کار اما جلوتر مثال‌هایی میبینیم که واضح‌تر میشه برامون. یک نکته دیگه باید بگم که وقتی از yield توی یک فانکشن‌ استفاده کنیم، وقتی اون فانکشن‌ را صدا میزنیم، یک Generator Object برای ما ایجاد میشه برخلاف وقتی که از return استفاده می‌کنیم و اون فانکشن‌ اجرا میشه و return یک مقداری را برمیگردونه و ما همون مقداری که برگردونده را داریم. پس نمیتونیم با صدا زدن معمولی یک تابع که yield داره از اون اطلاعاتمون را دریافت کنیم چون خروجی اون تابع یک Object هست. در ادامه در این باره بیشتر حرف می‌زنیم.وقتی ما از yield توی فانکشن‌ استفاده کنیم، اون فانکشن‌ میشه یک Generator Function که یک Generator Object برای ما برمیگردونه (منبع). بریم یک مثال ببینیم تا بیشتر جا بیوفته برامون.مثال از generator function و generator objectتوی مثال بالا می‌بینید که ما اومدیم یک فانکشن‌ به اسم generator_function ایجاد کردیم و توی اون یک حلقه for گذاشتیم که اعداد ۱ تا ۴ را برای ما با استفاده از دستور yield برمیگردونه. بعد از اون اومدیم یک حلقه for خارج از فانکشن‌ ایجاد کردیم و روی فانکشن‌ تکرار می‌کنیم و خروجی‌هاش را چاپ میکنیم. از مقاله قبلی دیگه میدونیم که داخل حلقه for چه اتفاقی میوفته. بخوایم بیشتر توضیح بدیم در حقیقت این قطعه کد میاد و روی generator object که فانکشن‌ ما برمیگردونه تکرار انجام میده تا جایی که StopIteration را raise کنه یعنی ساده تر بگیم تا جایی که دیگه yield نباشه توی فانکشن.نکته هیجان انگیز و مهم اینه که بر خلاف متد معمولی، generator در هر بار اجرا یا تکرار یکی از خروجی‌هاش را ایجاد میکنه. منظور از &#34;در هر بار اجرا&#34; یعنی هربار که next روی اون generator object صدا زده بشه (میدونیم توی for هم این اتفاق میوفته در حقیقت). خوبیش چیه؟ بسیار بسیار Memory Efficient تره یعنی مثلا فرض کنید توی همین مثال ساده بالا ما اگه می‌خواستیم از متد معمولی استفاده کنیم، باید یک list شامل همه عددهامون برمیگردوندیم و برنامه باید برای یک لیست کامل مموری درخواست می‌کرد. اما وقتی از generator استفاده می‌کنیم در هر بار تکرار یکی از عددهامون ایجاد میشه نه همش با هم! (منبع)در ادامه مثال قبل، اومدیم همون فانکشن‌ را صدا زدیم و داخل یک متغیر به اسم generator_object ریختیم. اگر type متغیرمون را چک کنیم میبینیم generator هست. اگر متد معمولی بود و return داشت، type متغیر ما برابر با type مقداری بود که فانکشن‌ برای ما برمی‌گردوند!خروجی کد بالا میشه:1&#xA;2&#xA;3&#xA;4&#xA;&lt;class &#39;generator&#39;&gt;&#xA;1&#xA;2&#xA;3&#xA;4توجه کنید که فانکشن داخل مثال بالا با فانکشن داخل مثال زیر یکی هستند و نباید فکر کنیم چون در فانکشن مثال بالا یک yield نوشته شده در واقع هم یک بار میتوان از ()next استفاده کرد، بلکه به تعداد تکرار حلقه for امکان صدا زدن ()next روی generator object ما وجود دارد.خروجی کد بالا هم عینا مثل مثال قبل خواهد بود.پس تا الان فهمیدیم که با استفاده از کلمه کلیدی yield چطور میتونیم generator ایجاد کنیم. اما استفاده از yield تنها راه ایجاد generator نیست.روش دوم استفاده از generator expression.احتمالا یک مقدار اگر با پایتون راحت باشید میدونید که با دستوری مثل دستور زیر، میشه یک list ایجاد کرد.خروجی دستور بالا یک لیست است.[1, 2, 3, 4]ایجاد یک generator با استفاده از generator expression خیلی شبیه به دستور بالاست اما تفاوتش اینه که به جای براکت دور دستور باید از پرانتز استفاده کنیم به صورت زیر:که خروجی دستور بالا به شکل زیر است:&lt;generator object &lt;genexpr&gt; at 0x7fc260d08308&gt;&#xA;1&#xA;2&#xA;3&#xA;4استفاده از generator expression ساده است و برای ایجاد generator به صورت on the fly یا درجا کاربرد داره.یک کاربرد بسیار خوب از این generator ها استفاده از آنها به عنوان ورودی فانکشن‌هاست. به عنوان مثال:در مثال بالا اعداد ۱ و ۲ و ۳ و ۴ توسط generator ایجاد و به فانکشن‌ها به عنوان ورودی داده وارد میشن و متدها عملایتشون را روی اون اعداد انجام میدن.خروجی مثال بالا:10&#xA;4چرا Generators؟خوب الان که میدونیم Generatorها در پایتون چی هستند، به این سوال میرسیم که چرا باید از اونا استفاده کرد و چرا بدردمون میخورن؟ (منبع)اول از همه اینکه پیاده‌سازی اونها راحته. همونطور که توی مثال اول کار دیدید، اگر میخواستیم یک Iterator توسط کلاس ایجاد کنیم دردسرش زیاد بود و واسه همین استفاده از Generator میتونه بهترین و منطقی‌ترین جایگزین باشه.دوم اینکه  Generatorها به شدت Memory Efficient هستند (همونطور که قبلا اشاره کردیم بهش) و به صورت بهینه از مموری استفاده می‌کنند و دلیلش را هم الان میدونیم. دلیلش اینه که در هر بار صدا زدن ()next روی Generator Object یکی از خروجی‌هاش در همون لحظه ایجاد میشه اما توی فانکشن معمولی اینطوری نیست.سومین دلیل امکان پیاده سازی دنباله بی‌نهایت با استفاده از Generatorها هست. ما میتوینم Generatorهایی تعریف کنیم که دنباله بی‌نهایتی از اعداد و ... را برای ما با هر بار صدا زدن برگردونن. به مثال زیر دقت کن:خروجی مثال بالا ۱ و ۲ و ۳ هست که هر بار ()next روی Generator Object ما صدا زده بشه یک خروجی ساخته میشه و چاپ میشه.چهارمین دلیل را با یک مثال به شدت زیبا که من عینا از اینجا برمیدارم براتون توضیح میدم. به نظرم این مثال زیبایی استفاده از Generatorها را در عمل نشون میده که چقدر میتونن کد را حرفه‌ای، ساده و بهینه کنن.فرض کنید یک فایل لاگ داریم که اطلاعات فروش یک پیتزا ? فروشی  را برای ما نگه میدارد. این فایل چند ستون دارد که ستون سوم آن نشان دهنده تعداد پیتزاهای فروخته شده در هر ساعت است. فرض کنید میخواهیم این فایل لاگ را بخوانیم و ببینیم این پیتزا فروشی چند پیتزا فروخته است؟بیا این مثال را با استفاده از Generator حل کنیم.توی مثال بالا ما فایل را با with اطلاعاتش را میخونیم، یک generator ایجاد میکنیم که با هر بار صدا زده شدن، یک خط از فایل را میخونه و ستون سوم اونا برمیگردونه پس تا اینجا از ذخیره خیلی از اطلاعات در حافظه پرهیز کردیم. در خط بعد یک generator ایجاد میکنیم که اطلاعات خرید پیتزا ? را به صورت عدد برای ما برمیگردونه. در حقیقت ما هر بار روی per_hour فانکشن ()next را صدا بزنیم، یک خط از فایل خونده می‌شه، و تعداد پیتزای ? فروخته شده در اون خط برگردونده میشه. حالا اگه به فانکشن ()sum بدیم per_hour را، حاصل پیتزا‌های ? فروخته شده برای ما برگردونده خواهد شد.بخش دوم مجموعه مفاهیمی در پایتون که شاید نمیدانید که در مورد Generatorها بود هم تمام شد.امیدوارم مفید بوده باشه و لذت برده باشید. سعی میکنم بخش سوم را سریع‌تر آماده کنم و لینکش را در همین‌جا قرار خواهم داد. خوشحال میشم اگر سوالی داشتید بپرسید و اگر براتون مفید بود، با دوستاتون به اشتراک بذارید. برای اینکه ادامه این مجموعه را از دست ندید من را در ویرگول فالو کنید.بخش‌های دیگر این مجموعه- مفاهیمی در پایتون که شاید نمیدانید - بخش اول - Iteratorsبا تشکر.</description><category>علی عابدی</category><author>علی عابدی</author><pubDate>Tue, 21 Apr 2020 15:31:28 +0430</pubDate></item><item><title>مفاهیمی در پایتون که شاید نمیدانید - بخش اول - Iterators</title><link>https://virgool.ir/@madensit/مفاهیمی-در-پایتون-که-شاید-نمیدانید-بخش-اول-y0ay1jfu72yd</link><description>مقدمههمه ما برنامه‌نویس‌ها می‌دانیم که حتی اگر به تمامی فوت و فن‌های یک زبان مسلط نباشیم هم میتوانیم از پس توسعه برنامه‌ها در آن زبان بربیاییم. بله! این یک واقعیت است، اما تمام واقعیت نیست. هرچند که اکثر ما برای نوشتن برنامه‌هایمان از تمامی امکانات و مفاهیم یک زبان برنامه‌نویسی استفاده نمی‌کنیم (چه خواسته و چه ناخواسته)، اما دانستن یک سری از مفاهیم قطعا در توسعه بهتر و حرفه‌ای‌تر نرم‌افزارهایمان به ما کمک خواهد کرد. این کمک می‌تواند در جهت ساده تر کردن کد، کوتاه‌تر کردن آن و یا حتی بهینه کردن آن باشد. تمامی زبان‌های برنامه نویسی، به خصوص زبان‌های سطح بالای جدید، علاوه بر مفاهیم پایه زبان‌ها، سعی در ارائه مفاهیمی می‌کند که کار را برای برنامه‌نویس راحت‌تر کرده و دست برنامه‌نویس را برای پیاده سازی مفاهیم پیچیده‌تر و به شکلی راحت‌تر، باز بگذارد. خوشبختانه پایتون دوست‌داشتنی نیز از این قاعده مستثنی نیست.در این سری از نوشته‌ها، میخواهم به مفاهیمی در زبان برنامه‌نویسی پایتون بپردازم که شاید کمتر مورد توجه قرار گرفته باشد. امیداوارم این سری از مطالب برای افرادی که تازه شروع به یادگیری پایتون کرده‌اند و یا در میانه راه قرار دارند مفید باشد. این مطالب از این یک منبع خاص نیست. اما سعی میکنیم در طول نوشته، منابعی که به آنها رجوع کرده‌ام را بیان کنم.بخش اول - Iteratorsمقدمه - Iterator چیست؟مفهوم Iterator در پایتون، از اون دسته از مفهوم هاست که احتمالا خیلی با اون کار کردیم اما دقیقا با اسم اون آشنایی نداریم.در پایتون، Iteratorها، objectهایی هستند که میتوانید روی آنها Iterate انجام دهیم! احتمالا همه ما با این توضیح اول کار گیج می‌شیم! بیا دقیق‌تر به اون بپردازیم.همونطور که احتمالا میدونی، همه چیز در پایتون object است (اگه نمیدونی، این مطلب شاید کمکت کنه، شاید بعدا در این باره نوشتم.) پس Iteratorها هم جدای از این حقیقت نیستند و ماهیت object دارند. پس تا اینجا بخش اول اون جمله پیچیده را تفکیک کردیم که خلاصه اون میشه : Iterator =&gt; Object. حالا بیا به بررسی قسمت دوم بپردازیم. ما به چه کاری Iteration میگوییم؟ ترجمه فارسی این کلمه می‌شه تکرار پس به تکرار کردن می‌گوییم!ما کجا در برنامه‌نویسی تکرار میکنیم؟ هر جایی که از حلقه به صورت مستقیم یا غیر مستقیم استفاده میکنیم.پس در حلقه‌ها ما Iteration انجام میدیم. (منبع)در نهایت می‌تونیم بگیم Iteratorها اشیایی هستند که ما روی اون‌ها در حلقه‌ها تکرار انجام میدیم.Iteratorها توی هر بار از تکرار حلقه‌ی ما یکی از داده‌هایی را برمیگردونند که ما داریم روی اونا تکرار را انجام می‌دیم.احتمالا اگه یک مقدار با پایتون آشنایی داشته باشی اولین چیزی که به ذهنت برای iterator رسیده، با توجه به تعاریف بالا، listها هستند. اما صبر کن! اول بیا یک مثال ببینیم.چاپ اعضای یک لیست در حلقه forاین مثال ساده ترین مثالیه که می‌تونیم در مورد چاپ اعضای یک لیست بزنیم. همینطور که می‌بینی ما یک حلقه داریم و اعضای لیست test_list را یکی یکی چاپ می‌کنیم. پس list یک Iterator است ؟ خیر!علاوه بر مفهوم iterator در پایتون، مفهوم دیگه‌ای به نام Iterable وجود داره و لیست یک نمونه از Iterableهاست.دو مفهوم شبیه ولی متفاوت - Iterable چیست؟اگه بخوایم ساده بگیم، Iterableها یک سری object هستند (که دیگه مشخص بود!) که می‌تونیم از روی اونا Iterator بسازیم. چطوری؟ با استفاده از ()iter که یک فانکشن built-in در پایتون هست.یک مثال برای درک تفاوت Iterator و Iterableخروجی کد بالا&lt;class &#39;list&#39;&gt;&#xA;&lt;class &#39;list_iterator&#39;&gt;&#xA;1&#xA;2&#xA;3کمی عمیق‌ترهمونطور که قبلا گفتیم، در پایتون این Iteratorها هستند که قابلیت این را دارند که بشود روی آنها تکرار انجام داد. اما سوال مهم اینه که پس چطور روی یک data type مثل list که iterable هست هم میشه حلقه for گذاشت؟برای درک این نکته باید حلقه for مثال قبل را به شکل دیگه‌ای نگاه کنیم (منبع) اما قبل از اون بیا کمی تخصصی‌تر در مورد Iterator و Iterableها بحث کنیم.همونطور که گفتیم این دو مفهوم، ماهیت object دارند پس می‌تونند متدهای خاص پایتون که به شکل __example__ هستند را داشته باشند. اما وجود چه متد‌هایی در یک object ماهیت Iterator بودن به اون میده و چه متد‌هایی خاصیت Iterable بودن؟اگه یک object متدهای __()iter__ و __()next__ را داشته باشه یعنی اون Iterator است. از طرف دیگه اگه یک object متد __()iter__ را فقط داشته باشه اون یک Iterable هست.این وسط یک نکته هم بد نیست اشاره کنیم که میتونیم تمام متد‌های یک کلاس را با  فانکشن‌ ()dir ببینیم.اگه بخواهیم به صورت دستی روی یک Iterator تکرار انجام دهیم از  فانکشن‌ ()next استفاده میکنیم.چاپ دستی اعضای یک iteratorخروجی کد بالا1&#xA;2&#xA;3توجه بشه که قبل از اینکه یک iterable را با استفاده از  فانکشن‌ ()iter تبدیل به iterator کنیم، امکان استفاده از  فانکشن‌ ()next بر روی اون وجود ندارد. چون  فانکشن‌ ()next در حقیقت متد __()next__ را صدا می‌زنه و همونطور که گفتیم iterableها متد __()next__ را ندارند. الان متوجه می‌شیم که وقتی  فانکشن‌ ()iter را صدا می‌زنیم، در حقیقت متد __()iter__ صدا زده می‌شه.الان می‌تونیم به این سوال پاسخ بدیم که در حقیقت در داخل حلقه for چه اتفاقی رخ می‌دهد؟چیزی که واقعا در حلقه for اتفاق میوفتدنکته قابل توضیح در مثال بالا اینه که وقتی  فانکشن‌ ()next به آخر iterator می‌رسه، StopIteration را raise می‌کند.بله درسته! وقتی ما در پایتون روی یک Iterable مثل list حلقه for میذاریم، ابتدا این لیست به یک Iterator تبدیل میشه و تا جایی که StopIteration را raise کنه ادامه پیدا میکنه.این بود مطلب من در مورد Iteratorهای جذاب داخل پایتون دوست داشتنی. شما خودتون هم میتونید iteratorهایی ایجاد کنید. کلاسی ایجاد کنید که متدهای __()iter__ و __()next__ را دارند و به همین راحتی iterator خودتون را ایجاد کنید.بخش اول مجموعه مفاهیمی در پایتون که شاید نمیدانید که در مورد Iteratorها بود تمام شد.امیدوارم مفید بوده باشه. خوشحال میشم اگر سوالی داشتید بپرسید و اگر براتون مفید بود، با دوستاتون به اشتراک بذارید. برای اینکه ادامه این مجموعه را از دست ندید من را در ویرگول فالو کنید.بخش‌های دیگر این مجموعه- مفاهیمی در پایتون که شاید نمیدانید - بخش دوم - Generatorsبا تشکر.</description><category>علی عابدی</category><author>علی عابدی</author><pubDate>Fri, 17 Apr 2020 20:42:04 +0430</pubDate></item></channel></rss>