5 تمرین عالی برای برنامه نویسی پیشرفته و شی گرایی در پایتون

شامل بهترین متدها برای مدیریت استثنائات ، نوشتن مستندات ، دکوراتور ها برای ارث بری کلاسی و بسته ها (Packages) که برای اصلاح کردن خودکار کد شما به کار می روند.ساختن کلاس های پایتون همواره سرگرم کننده اند. اما بسته بندی آنها برای بهره وری ، استفاده خارجی و مستندات بسیار مهم است. در این مقاله ، بنده 5 تا از بهترین تمرین ها برای مستند سازی ، نگهداری و تست کلاس های پایتون شما را شرح خواهم داد. این روش ها شامل بهترین راه ها برای مدیریت استثناها ، نوشتن مستندات و داک تست ها ، دکوراتور های ارث بری کلاس و مدیریت داده ها ، کلاس های انتزاعی و پکیج های خودکار برای اصلاح کردن و قالب بندی کد های شما.1- مدیریت استثنائاتساختن یک کلاس پایتون جالب است. اما مهم است هنگامی که ورودی های نادرست در تابع شما جای می گیرند ، مطمئن شوید اشتباهات را به درستی رفع کرده اید.در این جا چند مثال داریم : تصور کنید شما در حال ساختن یک تابع هستید که داده ی n از نوع Integer را دریافت کرده و یک آرایه n در n را با آن ایجاد می کنید. کد آن به شرح زیر است :import numpy as np class make_array(): def __init__(self, n): self.array = np.empty([n,n])حال ، بیایید تابع را با ورودی رشته ای به جای عدد صحیح تغذیه کنیم. هدف مان به مشروح زیر است:خطای نوع داده (TypeError) ، شیوا ترین پیام برای حل اشکال مسئله نیست ، مخصوصا اگر خروجی شما مورد استفاده مخاطبین گسترده ای قرار بگیرد. بیایید کمی تغیرات در کد ایجاد کنیم:import numpy as np class make_array(): def __init__(self, n): if type(n) != int: raise TypeError('Please input an integer. The size of the array has to be a positive integer.') if n <= 0: raise ValueError('Please provide a positive integer for the size of the array. \ It cannot be negative or zero.') self.array = np.empty([n,n])در کد فوق بررسی می شود که ورودی از نوع عدد صحیح است یا خیر. اگر نباشد ، خطای TypeError را با پیغامی مناسب نشان می دهد. همچنین منفی بودن عدد ورودی را چک می کند. اگر منفی باشد ، یک خطای مقدار(ValueError) را به نمایش می گذارد که کاربر را مجاب می کند یک عدد صحیح مثبت ارائه دهد.در اینجا چند مورد آزمایشی را مشاهده می کنید:چرا این مسئله ای مهم است؟ نمایش دادن درست پیام های بصری برای ساختن پکیجی که به راحتی اشکال زدایی می شود ، بسیار حائز اهمیت است.2- مستند سازیدر زمانی ، ما از comment ها برای توضیحات مناسب در کد خود استفاده می کردیم. اما کامنت ها ساختارمند ترین و روشی خوش نما برای سند سازی جریان کارمان نیستند. برای نوشتن مستندات ساختارمند در کد خود ؛ شما باید از سه علامت کوتیشن ( ‘ ) استفاده کنید. در اینجا مثالی را مشاهده می کنید:import numpy as np class make_array(): def __init__(self, n): ''' Make Array: The function takes a positive integer and builds an empty array of size n x n. Inputs: - n (Type: integer and positive) Attributes: - NumPy array with size n X n ''' if type(n) != int: raise TypeError('Please input an integer. The size of the \ array has to be a positive integer.') if n <= 0: raise ValueError('Please provide a positive integer for \ the size of the array. It cannot be negative or zero.') self.array = np.empty([n,n])در کد بالا کلیه اطلاعات در درون یک پاراگراف ، قبل از تابع قرار گرفته اند. تمامی آن در بین سه کوتیشن در آغاز و سه کوتیشن در انتها قرار گرفته اند. اغلب پیکیج های پایتون توسط این تکنیک مستند سازی شده اند.3- آزمایش کردندر اکثر مستندات پایتون ، توسعه دهندگان موارد کاربری مستند شده ای را برای تابع ها لحاظ می کنند. همچنین این موارد کاربری با عنوان ‘tests’ مورد استفاده قرار می گیرند تا مطمئن شویم تابع واکنش و پاسخ صحیحی از خود بروز می دهد. با آن شیوه مستند سازی که در بالا یاد گرفیتم ، ما همچنین قادر به نوشتن doc تست هایی هستیم که هم در موارد کاربری و هم در اجرای توابع کاربرد دارند. در این tests ها ، ما خروجی مد نظر را مشخص می کنیم. اگر خروجی واقعی با خروجی مورد نظر ما تطابق نداشته باشد ، doctest ناموفق بوده است. در اینجا مثالی از doctest آورده شده است که در درون تابعی که شناسه های تصادفی تولید می کند ، جای گرفته است:def random_id(length): &quot&quot&quot This function creates a random configuration key for a given length. Inputs: - length (Type: int and positive) Outputs: - ID (Type: str) DocTest 1 >>> len(random_id(50)) == 50 True DocTest2 >>> random_id('hello') Traceback (most recent call last): ... TypeError: The input must be a positive integer. &quot&quot&quot if type(length) != int or length < 1: raise TypeError('The input must be a positive integer.') choices = '0123456789abcdefghijklmnopqrstuvwxyz' id = '' for _ in range(length): id += random.choice(choices) return idدر مستندات فوق ، doctest ها با علامت ‘>>>’ مشخص شده اند. کد پایتون پس از آن علامت توسط مفسر doctests اجرا می شود. خروحی مد نظر زیر آن نشان داده شده است. اگر خطا باشد همانگونه که دربالا به نمایش آمده است ، در doctest دوم نشان داده می شود. بیایید همین فایل را با کتابخانه doctest اجرا کنیم.شما باید کد زیر را در انتهای فایل .py که حاوی کد بالاست اضافه کنید:if __name__ == &quot__main__&quot: import doctest doctest.testmod()حال ، بیایید داک تست خود را با فرمان Bash اجرا کنیم (من نام فایلم را random_id.py گذاشته ام):python random_id.py –vدر نتیجه ، کد ما تمامی داک تست ها را با موفقیت پشت سر گذاشت. اما این داک تست ها بسیار ساده بودند. شما می توانید خودتان داک تست های پیچیده تری بنویسید. همانگونه که شما کلاس های پایتون را ویرایش و نگهداری می کنید ، اطمینان از عدم وجود هرگونه باگ و ایراد در داک تست که منجر به شکست بشود مهم است.4- پیروی کردن از رهنمود های pep8:دستورالعمل های pep8 قراداد های کدگذاری برای بسته های پایتون هستند. این در حالیست که این قرارداد ها سختگیرانه نیستند و بر درستی کد تاثیری ندارند. ارزش آن ها در خوانایی ، فهم و نگهداری آسان کد های نشر شده مشخص می شود. برخی از برجسته ترین دستورالعمل های آن به شرح زیر است :· هر خط از کد نباید فراتر از 80 کاراکتر باشد. اگر خطی بیشتر از این مقدار باشد ، شما می توانید از نشان ‘\’ برای نوشتن دنباله کد در خط بعد استفاده کنید. اگر ورودی ها را در یک تابع مشخص می کنید ، نیاز به انجام عملی نیست زیرا پایتون خود کد را ادامه می دهد. این مسئله تنها برای رشته ها می باشد و در این مواقع ‘\’ کاربرد دارد.· کلیه کتابخانه ها باید در ابتدا بدون هیچگونه تکراری درج شوند. چرا؟ اگر مشکلی برای وابستگی وجود داشته باشد ، قبل از زمان اجرای کد هایلایت می شوند و نه هنگام اجرا.· متغیر های زائد یا میانجی (که اقدامات دیگری انجام نمی دهند) باید حذف شده تا حافظه را اشغال نکنند.اما لازم نیست همه این دستورالعمل ها را به صورت دستی اجرا کنید. پکیج پایتونی وجود دارد که pycodestyle نامیده می شود و یک فایل پایتون را به عنوان ورودی دریافت می کند و تمام موارد آن را به شکل هایلایت در می آورد.بیاید pycodestyle را در همان فایل random_id.py اجرا کنیم. پیغام به ما می فهماند که خطوط کافی بین دو تابع وجود ندارد (دوسطر خالی توصیه می شود) و خط ششم نیز بسیاری طولانیست.همچنین شما می توانید بسته ای به نام autopep8 را اجرا کنید که یک فایل پایتون را می گیرد و مطابق رهنمود های 8pep ، به شکل خودکار آن را اصلاح می کند. در اینجا درباره استفاده ازautopep8 بیشتر بیاموزید.5- از کلاس های تجرید (انتزاعی) و وراثت استفاده کنید.در برنامه نویسی شی گرا ، باید میزان کد نویسی ما کاسته شود. این بدان معناست که یک کد نویس باید کلاسهایی را بسازد که انتزاعی بوده و بطور کلی در طیف وسیعی از اشیا قابل استفاده باشد. برای مثال من یک شبیه سازی از یک میز ساخته ام و به نوشتن کدی نیاز دارم که که شبیه سازی اشیایی همچون خودکار، دفترچه یادداشت ، مداد ، پاک کن و مداد تراش در خود داشته باشد.اما ما قصد نداریم که برای هر شی ، کلاس دیگری بنویسیم. ما یک کلاس انتزاعی می نویسیم و آنرا ‘Table_Object’ می نامیم. مطابق دستورات زیر:from abc import abstractclass class Table_Object(): def __init__(self, age): self.location = 'table-1' self.age = age @abstractclass def object_type(self): passطراحی کلاس انتزاعی فوق ، یک تابع خاص است که نوع شی را نشان می دهد. حال کلاس دیگری را تعریف می کنیم که از تمام داده های این کلاس با یک تابع مخصوص برای object_type ارث می برد.class pencil(Table_Object): made_of = 'wood' def object_type(self): return 'pencil' class paper(Table_Object): made_of = 'wood' def object_type(self): return 'paper'در اینجا ما دو کلاس تعریف کرده ایم که از کلاس Table_Object ارث می برند و بعد به کلاس های تخصصی ارث برده متصل می شوند تا به ایده ی بودن از اشیای میز تحقق ببخشند. کلاس وراثت امکان کاستن از تکرار را فراهم می کند و همچنین سلسله مراتبی از کلاسها را برای کد نویس محیا می کند که البته برای کد نویسی حرفه ای معقولانه نیست.علامت ‘@’ که در Table_Object میبینیم دکوراتور نامیده می شود. یک دکوراتور تابع ساده دیگری است که امکان اضافه کردن یک ویژگی خاص را به یک تابع دیگر فراهم می سازد. در کلاس های پایتون یک دکوراتور دیگر نیز وجود دارد که روش ایستا نامیده می شود. این متدها استاتیک هستند و هنگام فراخوانی کلاس را به ارث نمی برند. آن ها معمولا برای اینکه بخشی از کلاس تحت تاثیر تغیرات قرار نگیرند ، مورد استفاده قرار می گیرند.class Table_Object(): def __init__(self, age): self.location = 'table-1' self.age = age @staticmethod def object_location(): return 'Table'برای کلاس های مجهز به داده های تخصصی ، شما باید از دکوراتور های کلاس داده استفاده کنید. برای مطالعه بیشتر آن اینجا کلیک کنید.امیدواریم که ازخواندن این مقاله لذت برده باشید. در صورت داشتن هرگونه سوال میتوانید در LinkedIn من ، با بنده تماس بگیرید. برنامه نویسی تان مبارک!آدرس مقاله به زبان اصلی : https://towardsdatascience.com/5-best-practices-for-professional-object-oriented-programming-in-python-20613e08baee