سربارگذاری عملگرها در برنامه نویسی پایتون

4 سال پیش

سربارگذاری عملگرها در برنامه نویسی پایتون

در این درس از مجموعه آموزش برنامه نویسی سایت سورس باران، شما یاد خواهید گرفت که چگونه سربارگذاری عملگرها در برنامه نویسی پایتون (Python Operator Overloading) استفاده کنید

پیشنهاد ویژه : پکیج آموزش طراحی وب سایت با پایتون

سربارگذاری عملگرها در برنامه نویسی پایتون

اپراتورهای پایتون برای کلاس های توکار، کار می کنند. اما همان اپراتور با انواع مختلف رفتارهای متفاوتی دارد. به عنوان مثال، عملگر + جمع حساب را روی دو عدد انجام می دهد، دو لیست را ادغام می کند یا دو رشته را بهم می پیوندد.

به این ویژگی در پایتون که اجازه می دهد همان عملگر با توجه به زمینه معنای متفاوتی داشته باشد، سربارگذاری عملگرها در برنامه نویسی پایتون (Python Operator Overloading) نامیده می شود.

بنابراین چه اتفاقی می افتد که ما از آنها با اشیای یک کلاس تعریف شده توسط کاربر استفاده کنیم؟ بیایید کلاس زیر را در نظر بگیریم که سعی در شبیه سازی یک نقطه در سیستم مختصات ۲-D دارد.

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y


p1 = Point(1, 2)
p2 = Point(2, 3)
print(p1+p2)

 

خروجی

Traceback (most recent call last):
  File "<string>", line 9, in <module>
    print(p1+p2)
TypeError: unsupported operand type(s) for +: 'Point' and 'Point'

 

در اینجا، می توانیم ببینیم که یک TypeError مطرح شده است ، زیرا پایتون نمی دانست چگونه دو شی را به یکدیگر اضافه کند.

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

توابع ویژه پایتون

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

این توابع توابع معمولی نیستند که برای یک کلاس تعریف کنیم. تابع ()__init __  که در بالا تعریف کردیم یکی از آنهاست. هر وقت شی a جدیدی از آن کلاس ایجاد کنیم فراخوانی می شود.

توابع ویژه بیشمار دیگری نیز در پایتون وجود دارد.

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

>>> p1 = Point(2,3)
>>> print(p1)
<__main__.Point object at 0x00000000031F8CC0>

 

فرض کنید می خواهیم تابع ()print  به جای آنچه که به دست آوردیم مختصات شی Point را چاپ کند. ما می توانیم در کلاس خود یک روش()__str __  تعریف کنیم که نحوه چاپ شی را کنترل کند. بیایید ببینیم چگونه می توانیم به این هدف برسیم:

class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y
    
    def __str__(self):
        return "({0},{1})".format(self.x,self.y)

 

حالا بیایید دوباره تابع ()print را امتحان کنیم.

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __str__(self):
        return "({0}, {1})".format(self.x, self.y)


p1 = Point(2, 3)
print(p1)

 

خروجی

(۲, ۳)

معلوم است که وقتی از تابع ()str یا ()format استفاده می کنیم، همین روش فراخوانی می شود.

>>> str(p1)
'(۲,۳)'

>>> format(p1)
'(۲,۳)'

 

'

بنابراین ، وقتی از (str (p1 یا (format (p1 استفاده می کنید، پایتون به صورت داخلی روش ()p1 .__ str __  را فراخوانی می کند. از این رو نام آن، توابع ویژه است.

 

سربارگذاری عملگر + در پایتون
برای سربارگذاری عملگر + در برنامه نویسی پایتون، باید عملکرد() __add __ را در کلاس پیاده سازی کنیم.  در داخل این تابع می توانیم هر کاری را که دوست داریم انجام دهیم. اما منطقی تر است که یک شی از مقدار مختصات را برگردانیم

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __str__(self):
        return "({0},{1})".format(self.x, self.y)

    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Point(x, y)

 

حالا بیایید دوباره عمل جمع را امتحان کنیم:

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __str__(self):
        return "({0},{1})".format(self.x, self.y)

    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Point(x, y)


p1 = Point(1, 2)
p2 = Point(2, 3)

print(p1+p2)

 

خروجی

(۳,۵)

 

آنچه در واقع اتفاق می افتد این است که ، وقتی از p1 + p2 استفاده می کنید، پایتون p1 را فراخوانی می کند که به نوبه خود(Point.__add__(p1,p2) است. پس از این، عملیات جمع به روشی که مشخص کردیم انجام می شود.

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

عملگر اصطلاح داخلی
جمع p1 + p2 (p1.__add__(p2
تفریق p1 - p2 (p1.__sub__(p2
ضرب p1 * p2 (p1.__mul__(p2
توان p1 ** p2 (p1.__pow__(p2
تقسیم p1 / p2 (p1.__truediv__(p2
جزء صحیح p1 // p2 (p1.__floordiv__(p2
باقیمانده p1 % p2 (p1.__mod__(p2
Bitwise Left Shift p1 << p2 (p1.__lshift__(p2
Bitwise Right Shift p1 >> p2 (p1.__rshift__(p2
Bitwise AND p1 & p2 (p1.__and__(p2
Bitwise OR p1 | p2 (p1.__or__(p2
Bitwise XOR p1 ^ p2 (p1.__xor__(p2
Bitwise NOT ~p1 (p1.__invert__()

سربارگذاری عملگرها مقایسه

پایتون سربارگذاری عملگرها را فقط به عملگرهای حساب محدود نمی کند. ما می توانیم عملگرهای مقایسه را نیز اضافه بار دهیم.

فرض کنید می خواستیم نماد کمتر از نماد <را در کلاس Point خود پیاده کنیم.

اجازه دهید مقدار این نقاط را از مبدا مقایسه کنیم و نتیجه را برای این منظور برگردانیم.

# overloading the less than operator
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __str__(self):
        return "({0},{1})".format(self.x, self.y)

    def __lt__(self, other):
        self_mag = (self.x ** 2) + (self.y ** 2)
        other_mag = (other.x ** 2) + (other.y ** 2)
        return self_mag < other_mag

p1 = Point(1,1)
p2 = Point(-2,-3)
p3 = Point(1,-1)

# use less than
print(p1<p2)
print(p2<p3)
print(p1<p3)

 

خروجی

True
False
False

 

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

عملگر اصطلاح داخلی
کوچکتر p1 < p2 (p1.__lt__(p2
کوچکتر مساوی p1 <= p2 (p1.__le__(p2
برابر است یا p1 == p2 (p1.__eq__(p2
برابر نیست p1 != p2 (p1.__ne__(p2
بزرگتر p1 > p2 (p1.__gt__(p2
بزرگتر مساوی p1 >= p2 (p1.__ge__(p2

منبع.

لیست جلسات قبل آموزش برنامه نویسی پایتون

  1. آموزش نصب و اجرای برنامه نویسی پایتون
  2. کلیدواژه ها و شناسه های برنامه نویسی پایتون
  3. دستورات، تورفتگی ها و کامنت ها در برنامه نویسی پایتون
  4. متغیرها، ثابت ها و لیترال ها در برنامه نویسی پایتون 
  5. انواع داده ها در برنامه نویسی پایتون
  6. تبدیل نوع در برنامه نویسی پایتون
  7. ورودی، خروجی و وارد کردن در برنامه نویسی پایتون
  8. عملگرها در برنامه نویسی پایتون
  9. نام و دامنه در برنامه نویسی پایتون
  10. دستور شرطی if…else در برنامه نویسی پایتون
  11. حلقه for در برنامه نویسی پایتون
  12. حلقه while در برنامه نویسی پایتون
  13. دستورات break و continue در برنامه نویسی پایتون
  14. دستور pass در برنامه نویسی پایتون
  15. توابع در برنامه نویسی پایتون
  16. آرگومان تابع در برنامه نویسی پایتون
  17. تابع بازگشتی در برنامه نویسی پایتون
  18. تابع بی نام/ تابع لامبدا در برنامه نویسی پایتون
  19. متغیرهای سراسری، محلی و غیر محلی در برنامه نویسی پایتون
  20. کلیدواژه global در برنامه نویسی پایتون
  21. ماژول های برنامه نویسی پایتون
  22. پکیج ها در برنامه نویسی پایتون
  23. اعداد و تبدیل نوع داده در برنامه نویسی پایتون 
  24. لیست در برنامه نویسی پایتون
  25. تاپل در برنامه نویسی پایتون 
  26. رشته ها در برنامه نویسی پایتون
  27. مجموعه ها در برنامه نویسی پایتون
  28. دیکشنری در برنامه نویسی پایتون
  29. عملیات ورودی/خروجی در برنامه نویسی پایتون 
  30. دایرکتوری و مدیریت فایل ها در برنامه نویسی پایتون
  31. خطاها و استثناهای توکار در برنامه نویسی پایتون
  32. مدیریت استثناها در برنامه نویسی پایتون
  33. استثناهای تعریف شده توسط کاربر در برنامه نویسی پایتون
  34. برنامه ‌نویسی شی گرا در پایتون
  35. اشیا و کلاس ها در برنامه نویسی پایتون
  36. وراثت در برنامه نویسی پایتون
  37. وراثت چندگانه در برنامه نویسی پایتون

 

0
برچسب ها :
نویسنده مطلب erfan molaei

دیدگاه شما

بدون دیدگاه