از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
بارگذاری بیش از حد توابع و عملگرها در پایتون
سرفصلهای مطلب
اضافه بار چیست؟
اضافه بار، در زمینه برنامه نویسی، به توانایی یک تابع یا یک اپراتور برای رفتار به روش های مختلف بستگی دارد. روی پارامترهایی که به تابع ارسال می شوند یا عملوندهایی که عملگر عمل می کند روی. در این مقاله خواهیم دید که چگونه میتوانیم اضافه بار تابع و بارگذاری اپراتور را در پایتون انجام دهیم.
بارگذاری بیش از حد یک روش قابلیت استفاده مجدد را تقویت می کند. به عنوان مثال، به جای نوشتن چندین روش که فقط اندکی با هم تفاوت دارند، می توانیم یک متد را بنویسیم و آن را بیش از حد بارگذاری کنیم. اضافه بار نیز وضوح کد را بهبود می بخشد و پیچیدگی را از بین می برد.
اضافه بار مفهومی بسیار مفید است. با این حال، یک سری معایب مرتبط با آن دارد. وقتی بیش از حد از مرزهای وراثت استفاده می شود، اضافه بار می تواند باعث سردرگمی شود. هنگامی که بیش از حد مورد استفاده قرار می گیرد، مدیریت توابع اضافه بار دشوار می شود.
در بخش باقی مانده از این مقاله، ما به طور مفصل در مورد اضافه بار عملکرد و اپراتور بحث خواهیم کرد.
بارگذاری بیش از حد تابع در پایتون
بسته به روی چگونه تابع تعریف شده است، می توانیم آن را با پارامترهای صفر، یک، دو یا حتی بسیاری فراخوانی کنیم. این به عنوان “بارگذاری بیش از حد عملکرد” شناخته می شود.
اضافه بار عملکرد به دو نوع تقسیم می شود: اضافه بار توابع داخلی و اضافه بار توابع سفارشی. هر دو نوع را در بخش های آینده بررسی خواهیم کرد.
بارگذاری بیش از حد توابع داخلی
این امکان برای ما وجود دارد که رفتار پیش فرض توابع داخلی پایتون را تغییر دهیم. ما فقط باید متد خاص مربوطه را در کلاس خود تعریف کنیم.
اجازه دهید این را با استفاده از پایتون نشان دهیم len()
تابع روی کلاس خرید ما:
class Purchase:
def __init__(self, basket, buyer):
self.basket = list(basket)
self.buyer = buyer
def __len__(self):
return len(self.basket)
purchase = Purchase(('pen', 'book', 'pencil'), 'Python')
print(len(purchase))
خروجی:
3
برای تغییر روش len()
تابع رفتار می کند، ما یک متد خاص به نام تعریف کردیم _len_()
در کلاس ما. هر زمان که یک شی از کلاس خود را به آن ارسال کنیم len()
، نتیجه با فراخوانی تابع تعریف شده سفارشی ما به دست می آید، یعنی _len_()
.
خروجی نشان می دهد که ما قادر به استفاده هستیم len()
برای بدست آوردن طول سبد
اگر تماس بگیریم len()
روی شی بدون __len__()
عملکرد بیش از حد بارگذاری شده است، مانند شکل زیر یک TypeError دریافت خواهیم کرد:
class Purchase:
def __init__(self, basket, buyer):
self.basket = list(basket)
self.buyer = buyer
purchase = Purchase(('pen', 'book', 'pencil'), 'Python')
print(len(purchase))
خروجی:
Traceback (most recent call last):
File "C:/Users/admin/func.py", line 8, in <module>
print(len(purchase))
TypeError: object of type 'Purchase' has no len()
توجه: پایتون انتظار دارد len()
تابع برای برگرداندن یک عدد صحیح، از این رو این باید در هنگام بارگذاری بیش از حد تابع در نظر گرفته شود. اگر انتظار می رود تابع اضافه بار شما به غیر از یک عدد صحیح، چیز دیگری را برگرداند، یک TypeError دریافت خواهید کرد.
ما می توانیم رفتار را تغییر دهیم len()
روش در مثال بالا از درون تعریف پیاده سازی آن، یعنی __len__()
. به جای اینکه طول سبد را برگردانیم، اجازه دهید چیز دیگری را برگردانیم:
class Purchase:
def __init__(self, basket, buyer):
self.basket = list(basket)
self.buyer = buyer
def __len__(self):
return 10;
purchase = Purchase(('pen', 'book', 'pencil'), 'Python')
print(len(purchase))
خروجی:
10
به جای برگرداندن طول سبد، اکنون مقداری را که ما مشخص کرده ایم برمی گرداند.
بارگذاری بیش از حد توابع تعریف شده توسط کاربر
برای بارگذاری بیش از حد یک تابع تعریف شده توسط کاربر در پایتون، باید منطق تابع را به گونه ای بنویسیم که بسته به پارامترهای ارسال شده، یک قطعه کد متفاوت در داخل تابع اجرا شود. به مثال زیر دقت کنید:
class Student:
def hello(self, name=None):
if name is not None:
print('Hey ' + name)
else:
print('Hey ')
std = Student()
std.hello()
std.hello('Nicholas')
خروجی:
Hey
Hey Nicholas
ما کلاس را ایجاد کرده ایم Student
با یک تابع به نام hello()
. کلاس پارامتر را می گیرد name
که تنظیم شده است None
. این بدان معناست که متد را می توان با یا بدون پارامتر فراخوانی کرد.
ما یک نمونه از کلاس ایجاد کرده ایم که برای دو بار فراخوانی تابع استفاده شده است، اول با پارامترهای صفر و دوم با یک پارامتر. ما اضافه بار تابع را پیاده سازی کرده ایم زیرا دو راه برای فراخوانی تابع وجود دارد.
اکنون می دانیم که بارگذاری بیش از حد تابع چگونه کار می کند، بخش بعدی تمرکز می کند روی اضافه بار اپراتور
بارگذاری بیش از حد اپراتور
پایتون به ما اجازه می دهد تا رفتار پیش فرض یک اپراتور را بسته به آن تغییر دهیم روی عملوندهایی که استفاده می کنیم این عمل به عنوان “اپراتور اضافه بار” نامیده می شود.
عملکرد عملگرهای پایتون بستگی دارد روی کلاس های داخلی با این حال، یک اپراتور زمانی که برای انواع مختلف اعمال می شود، رفتار متفاوتی خواهد داشت. یک مثال خوب عملگر “+” است. این عملگر در صورت اعمال یک عملیات حسابی انجام می دهد روی دو عدد، دو رشته را به هم متصل می کند و دو لیست را ادغام می کند.
نمونه هایی از بارگذاری بیش از حد اپراتور
برای مشاهده بارگذاری بیش از حد عملگر پایتون، پایتون را اجرا کنید terminal و دستورات زیر را اجرا کنید:
>>> 4 + 4
8
>>> "Py" + "thon"
'Python'
در دستور اول از عملگر “+” برای جمع کردن دو عدد استفاده کرده ایم. در دستور دوم از همان عملگر برای به هم پیوستن دو رشته استفاده کردیم.
در این مورد، عملگر “+” دو تفسیر دارد. هنگامی که برای اضافه کردن اعداد استفاده می شود، به عنوان “عملگر جمع” نامیده می شود. هنگامی که برای افزودن رشته ها استفاده می شود، به عنوان “اپراتور الحاق” شناخته می شود. به طور خلاصه، می توان گفت که عملگر “+” برای بیش از حد بارگذاری شده است int
و str
کلاس ها.
برای دستیابی به بارگذاری بیش از حد اپراتور، یک متد خاص را در تعریف کلاس تعریف می کنیم. نام روش باید با زیرخط دوتایی (__) شروع و به پایان برسد. عملگر + با استفاده از روش خاصی به نام بارگذاری می شود __add__()
. این روش توسط هر دو اجرا می شود int
و str
کلاس ها.
عبارت زیر را در نظر بگیرید:
x + y
پایتون عبارت را به صورت تفسیر می کند x.__add__(y)
. نسخه از __add__()
که نامیده می شود بستگی دارد روی انواع x
و y
. مثلا:
>>> x, y = 5, 7
>>> x + y
12
>>> x.__add__(y)
12
>>>
مثال بالا روش استفاده از عملگر + و همچنین روش خاص آن را نشان می دهد.
مثال زیر روش بارگذاری اپراتورهای مختلف در پایتون را نشان می دهد:
import math
class Point:
def __init__(self, xCoord=0, yCoord=0):
self.__xCoord = xCoord
self.__yCoord = yCoord
def get_xCoord(self):
return self.__xCoord
def set_xCoord(self, xCoord):
self.__xCoord = xCoord
def get_yCoord(self):
return self.__yCoord
def set_yCoord(self, yCoord):
self.__yCoord = yCoord
def get_position(self):
return self.__xCoord, self.__yCoord
def move(self, p, q):
self.__xCoord += p
self.__yCoord += q
def __add__(self, point_ov):
return Point(self.__xCoord + point_ov.__xCoord, self.__yCoord + point_ov.__yCoord)
def __sub__(self, point_ov):
return Point(self.__xCoord - point_ov.__xCoord, self.__yCoord - point_ov.__yCoord)
def __lt__(self, point_ov):
return math.sqrt(self.__xCoord ** 2 + self.__yCoord ** 2) < math.sqrt(point_ov.__xCoord ** 2 + point_ov.__yCoord ** 2)
def __gt__(self, point_ov):
return math.sqrt(self.__xCoord ** 2 + self.__yCoord ** 2) > math.sqrt(point_ov.__xCoord ** 2 + point_ov.__yCoord ** 2)
def __le__(self, point_ov):
return math.sqrt(self.__xCoord ** 2 + self.__yCoord ** 2) <= math.sqrt(point_ov.__xCoord ** 2 + point_ov.__yCoord ** 2)
def __ge__(self, point_ov):
return math.sqrt(self.__xCoord ** 2 + self.__yCoord ** 2) >= math.sqrt(point_ov.__xCoord ** 2 + point_ov.__yCoord ** 2)
def __eq__(self, point_ov):
return math.sqrt(self.__xCoord ** 2 + self.__yCoord ** 2) == math.sqrt(point_ov.__xCoord ** 2 + point_ov.__yCoord ** 2)
point1 = Point(2, 4)
point2 = Point(12, 8)
print("point1 < point2:", point1 < point2)
print("point1 > point2:", point1 > point2)
print("point1 <= point2:", point1 <= point2)
print("point1 >= point2:", point1 >= point2)
print("point1 == point2:", point1 == point2)
خروجی:
point1 < point2: True
point1 > point2: False
point1 <= point2: True
point1 >= point2: False
point1 == point2: False
ما دو ویژگی خصوصی در کلاس Point داریم، یعنی: __xCoord
و __yCoord
نشان دهنده مختصات دکارتی به نام xCoord
و yCoord
. ما متدهای setter و getter را برای این ویژگی ها تعریف کرده ایم. این get_position()
روش به ما کمک می کند موقعیت فعلی را در حالی که the move()
روش به ما کمک می کند مختصات را تغییر دهیم.
خط زیر استخراج شده از کد را در نظر بگیرید:
def __add__(self, point_ov):
خط به ما کمک می کند تا عملگر + را برای کلاس خود بارگذاری کنیم. این __add__()
متد باید یک شی Point جدید با اضافه کردن مختصات تکی یک شی Point به یک شی Point دیگر ایجاد کند. در نهایت شی جدید ایجاد شده را به تماس گیرنده برمی گرداند. این به ما کمک می کند عباراتی مانند:
point3 = point1 + point2
پایتون موارد فوق را به این صورت تفسیر خواهد کرد point3 = point1.__add__(point2)
. سپس آن را فراخوانی می کند __add__()
روش اضافه کردن دو شی نقطه نتیجه به “point3” اختصاص داده می شود.
توجه داشته باشید که یکبار __add__()
روش نامیده می شود، مقدار point1
اختصاص داده خواهد شد self
پارامتر در حالی که مقدار point2
اختصاص داده خواهد شد point_ov
پارامتر. تمام روش های خاص دیگر به روشی مشابه کار خواهند کرد.
اپراتورها برای اضافه بار
جدول زیر تعدادی از عملگرهای ریاضی که معمولاً سربارگذاری میشوند و روش کلاس برای اضافه بار نشان میدهد:
اپراتور | روش |
---|---|
+ |
__add__(self, other) |
- |
__sub__(self, other) |
* |
__mul__(self, other) |
/ |
__truediv__(self, other) |
% |
__mod__(self, other) |
< |
__lt__(self, other) |
<= |
__le__(self, other) |
== |
__eq__(self, other) |
!= |
__ne__(self, other) |
> |
__gt__(self, other) |
>= |
__ge__(self, other) |
نتیجه
پایتون هم از بارگذاری بیش از حد تابع و هم اپراتور پشتیبانی می کند. در بارگذاری بیش از حد تابع، میتوانیم از یک نام برای بسیاری از توابع پایتون استفاده کنیم، اما با تعداد یا نوع پارامترهای مختلف. با بارگذاری بیش از حد اپراتور، میتوانیم معنای عملگر پایتون را در محدوده یک کلاس تغییر دهیم.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-26 12:01:02