متدهای جادویی در پایتون یا آنچه که در اصطلاحات برنامهنویسی پایتون به آنها Dunder methods گفته میشود، یکی از ویژگیهای جالب و قدرتمند در برنامهنویسی شیءگرا هستند. این متدها، که با دو زیرخط (دبل آندر اسکور) در ابتدا و انتهای خود شناخته میشوند، به برنامهنویسان امکان میدهند تا رفتار کلاسها و اشیاء پایتون را در موقعیتهای مختلف کنترل و سفارشیسازی کنند.
با استفاده از متدهای جادویی در پایتون، میتوانید عملیاتی مانند مقایسه، جمع، ضرب، تبدیل به رشته و… را در کلاسها و اشیاء خودتان تعریف کنید و هر جا نیاز بود از آنها به شیوهای مشابه با انواع دادههای داخلی پایتون بهرهبرداری کنید. در این مقاله، به بررسی برخی از مهمترین و پرکاربردترین این متدها میپردازیم.
1. __new__ : تخصیص حافظه برای اشیاء
متد __new__
در واقع اولین متدی است که هنگام ساخت یک شیء جدید فراخوانی میشود. این متد قبل از __init__ اجرا میشود و هدف آن تخصیص حافظه برای شیء جدید است. به طور کلی، استفاده از این متد رایج نیست؛ اما در برخی موارد خاص، مانند پیادهسازی الگوی Singleton (که تنها یک نمونه از شیء ساخته شود)، بسیار مفید است.
2. __init__ : مقداردهی اولیه به اشیاء
متد __init__
یکی از شناختهشدهترین متدهای جادویی است که پس از تخصیص حافظه و ایجاد شیء فراخوانی میشود. این متد به شما اجازه میدهد تا مقادیر اولیهی ویژگیهای شیء را تعیین کنید و به نوعی کار مقداردهی اولیه را انجام میدهد. این متد تقریباً در هر کلاس پایتونی که برای آن شیءسازی انجام میشود استفاده میشود.
3. __str__ : نمایش شیء به صورت رشتهای خوانا
به طور پیشفرض، زمانی که شیء را با print چاپ میکنید، پایتون آدرس حافظه آن شیء را نشان میدهد که معمولاً برای کاربر قابل فهم نیست. با تعریف متد __str__
میتوان یک نمایش قابل خواندن و تفسیر از شیء فراهم کرد. این متد در نمایش اطلاعات به کاربران نهایی بسیار کارآمد است.
مثالی برای دو متد __init__
و __str__
که برای مقداردهی اولیه و نمایش شیء به صورت رشتهای خوانا استفاده میشوند:
در اینجا، متد init برای مقداردهی اولیه به ویژگیهای name و age استفاده شده و str هم نحوهی نمایش شیء را در حالت خوانا تعیین کرده است.
4. __int__ : تبدیل شیء به نوع صحیح
اگر بخواهید یک شیء خاص را به نوع صحیح (int) تبدیل کنید، از این متد استفاده میشود. مثلاً، در صورتی که یک کلاس تعریف کردهاید و میخواهید با تابع int آن را به عدد صحیح تبدیل کنید، میتوانید متد __int__ را سفارشیسازی کنید تا این عملیات به دلخواه شما انجام شود.
5. __len__ : طول شیء
این متد زمانی به کار میرود که بخواهید طول یک شیء را مشخص کنید. برای مثال، زمانی که تابع len() روی شیء شما فراخوانی شود، پایتون به دنبال این متد میگردد تا نتیجه را بازگرداند. در انواع خاصی از کلاسها، مانند لیستها یا رشتهها، این متد بسیار پرکاربرد است.
در اینجا، با استفاده از __len__
، تابع len()
روی شیء ml
کار میکند و طول لیست را برمیگرداند.
6. __call__ : فراخوانی شیء به عنوان تابع
زمانی که شیء یک کلاس را به عنوان یک تابع فراخوانی میکنید (مثلاً obj())، متد __call__
فراخوانی میشود. این متد میتواند در مواقعی مفید باشد که بخواهید اشیاء کلاس را به صورت توابع قابل اجرا تعریف کنید.
این سه متد جادویی برای کار با اشیاءی که دارای عناصر داخلی هستند (مانند دیکشنریها یا لیستها) بسیار کارآمد هستند:
__getitem__
زمانی اجرا میشود که بخواهید به یک عنصر خاص از شیء دسترسی پیدا کنید (obj[key]).__setitem__
زمانی به کار میرود که بخواهید یک مقدار را به عنصر خاصی از شیء اختصاص دهید (obj[key] = value).__delitem__
نیز برای حذف یک عنصر خاص از شیء مورد استفاده قرار میگیرد (del obj[key]).
در این مثال، __getitem__
برای دریافت یک عنصر از لیست سفارشی استفاده شده و __setitem__
برای تنظیم مقدار یک عنصر به کار رفته است.
8. __contains__ : بررسی وجود عنصر
این متد زمانی فراخوانی میشود که از عملگر in استفاده کنید. برای مثال، زمانی که item in obj را اجرا میکنید، پایتون متد __contains__
را فراخوانی میکند تا ببیند آیا آن عنصر خاص در شیء وجود دارد یا خیر.
9. __bool__ : تعیین مقدار بولین شیء
در مواقعی که نیاز دارید شیء شما در یک عبارت شرطی (if یا while) استفاده شود، متد __bool__
به کار میآید. با تعریف این متد، میتوانید مشخص کنید که در چنین شرایطی، شیء شما به عنوان True یا False تلقی شود.
10. __iter__ : ایجاد قابلیت تکرارپذیری
این متد در مواقعی به کار میرود که بخواهید روی یک شیء تکرار (iteration) انجام دهید. برای مثال، در عبارت for x in obj، پایتون متد __iter__
را فراخوانی میکند تا به آیتمهای شیء دسترسی پیدا کند.
11. متدهای مقایسهای: __eq__, __ne__, __gt__, __lt__, __le__, __ge__
این متدها برای انجام مقایسه بین دو شیء استفاده میشوند. با استفاده از این متدها میتوان شیء را با سایر شیءها از نظر برابری (==)، نابرابری (!=)، بزرگتر (>)، کوچکتر (<)، بزرگتر یا مساوی (>=) و کوچکتر یا مساوی (<=) مقایسه کرد.
12. __add__ و __mul__ : عملیات ریاضی
این دو متد برای انجام عملیات جمع (+) و ضرب (*) بین اشیاء استفاده میشوند. این قابلیت به شما اجازه میدهد تا عملیات ریاضی خاصی را بین اشیاء کلاس خودتان تعریف کنید.
اینجا متد __add__
تعریف شده تا عمل جمع برای دو بردار قابل انجام باشد.
13. __abs__, __neg__, و __invert__ : عملیات ریاضی تکعملگری
__abs__
زمانی فراخوانی میشود که تابع abs() روی شیء اعمال میشود.__neg__
برای اجرای عملگر منفی (-) روی شیء استفاده میشود.__invert__
برای عملگر ~ تعریف میشود و شیء را به صورت بیت به بیت معکوس میکند.