تور آموزشی

کلاس در پایتون

کلاس Class

کلاس در پایتون اگر نگوییم مهم‌ترین قطعا یکی از مهم‌ترین مفاهیم شی‌گرایی است. این موضوع به زبان برنامه‌نویسی پایتون اختصاص ندارد و در هر زبان دیگری که از شی‌گرایی پشتیبانی می‌کند برقرار است.

تقریبا هر چیزی در زبان پایتون یک شیء است. بنابراین ویژگی‌ها و متدهای خودش را دارد.

برای وارد شدن به بحث شی‌گرایی در پایتون باید با مفاهیم کلاس (class)، شیء (object)، ویژگی (property) و متد (method) آشنا شویم.

کلاس در زبان پایتون با کلمه کلیدی class تعریف می‌شود. هر نمونه (instance) از کلاس یک شیء نامیده می‌شود. از هر کلاس می‌توان اشیاء زیادی ایجاد کرد. هر شیء دارای ویژگی و متد است.

ویژگی (property)

در مثال زیر سعی می‌کنیم یک کلاس به نام Circle برای شکل هندسی دایره بنویسیم و مفهوم ویژگی در کلاس را توضیح دهیم.

مثال:

class Circle:
    center = [0, 0]
    radius = 1
my_circle = Circle()
print(my_circle.radius)
print(my_circle.center[0], my_circle.center[1])

خروجی:

1
0 0

در خط اول نام کلاس را مشخص کرده‌ایم. در خط 2 و 3 دو ویژگی برای کلاس تعریف کرده‌ایم. یکی برای مختصات مرکز دایره و دیگری برای اندازه شعاع دایره و به صورت پیش‌فرض مقادیری به آنها نسبت داده‌ایم. تا اینجا کار تعریف کلاس به پایان رسید. در خط 4 یک شی‌ء به نام my_circle از کلاس Circle ایجاد کرده‌ایم. در خط 5 و خط 6 شعاع و مرکز دایره را چاپ کرده‌ایم.

می‌توانیم مقدار این ویژگی‌ها را تغییر دهیم.

my_circle.radius = 3

معمولا نام کلاس‌ها در زبان پایتون به روش CamelCase نوشته می‌شود. یعنی حرف اول بزرگ و برای اسم‌های چندکلمه‌ای نیز حرف اول هر کلمه بزرگ است.

متد (method)

حال برای این کلاس یک تابع تعریف می‌کنیم که مساحت دایره را حساب می‌کند. به توابعی که درون کلاس تعریف می‌شوند متد (method) می‌گویند.

مثال:

class Circle:
    center = [0, 0]
    radius = 1
         
    def area(self):
        return 3.14 * self.radius * self.radius
 
print(my_circle.area())
my_circle.radius = 5
print(my_circle.area())

خروجی:

3.14
78.5

لازم به ذکر است که self یک پارامتر است که به نمونه فعلی ساخته شده از کلاس ارجاع می‌دهد. از self در متدهای کلاس و برای دسترسی به ویژگی‌های کلاس استفاده می‌کنیم.

متد __init__

تا اینجا یک کلاس با دو ویژگی و یک متد ساختیم. این ساده‌ترین حالت ساخت یک کلاس است. معمولا در زبان پایتون کلاس‌ها را کمی متفاوت‌تر تعریف می‌کنند. برای اینکه مفهوم کلاس در زبان پایتون را درک کنیم باید با تابع __init__ آشنا شویم (البته از آنجا که درون کلاس تعریف می‌شود از این به بعد به آن متد می‌گوییم).

متد __init__ در زبان پایتون همان مفهوم سازنده (constructor) در زبان‌های دیگر مانند سی‌پلاس‌پلاس و جاوا است. هر زمانی که یک شیء جدید ساخته می‌شود این متد فراخوانی می‌شود و ویژگی‌ها (property) را مقداردهی اولیه می‌کند. همه کلاس‌ها این متد را دارند. کلاس دایره را با این متد را بازنویسی می‌کنیم.

مثال:

class Circle:
    def __init__(self, r, c):
        self.radius = r
        self.center = c
         
    def area(self):
        return 3.14 * self.radius * self.radius
 
my_circle = Circle(3, [1, 1])
print(my_circle.radius)
print(my_circle.center)
print(my_circle.area())

خروجی:

3
[1, 1]
28.259999999999998

در اینجا نام ویژگی‌های کلاس (radius و center) در متد __init__ مشخص شده است.

در صورتی که بخواهیم مقادیر شعاع و مرکز دایره هنگام ساخته شدن شیء به صورت پیش‌فرض تعیین شوند این کار را در متد __init__ انجام می‌دهیم.

def __init__(self):
    self.radius = 1
    self.center = [0, 0]

متد __str__

از متد __str__ در زبان پایتون برای چاپ کردن نام شی‌های کلاس استفاده می‌شود. مشابه با متد __init__ این متد نیز به صورت پیش‌فرض برای همه کلاس‌ها وجود دارد.

ابتدا بدون اینکه این متد را برای کلاس circle بازنویسی کنیم سعی می‌کنیم از کلاس، print بگیریم.

مثال:

class Circle:
    def __init__(self):
        self.radius = 1
        self.center = [0, 0]
         
    def area(self):
        return 3.14 * self.radius * self.radius
my_circle = Circle()
print(my_circle)

خروجی:

<__main__.Circle object at 0x000001D586D75148>

اکنون متد __str__ را بازنویسی می‌کنیم. می‌خواهیم زمانی که شیء را چاپ می‌کنیم یک رشته متناسب با ویژگی‌های شیء چاپ شود. در مثال پایین مقدار شعاع و مختصات مرکز دایره را چاپ می‌کنیم.

مثال:

class Circle:
     def __init__(self):
          self.radius = 1
          self.center = [0, 0]
    
     def __str__(self):
          return "radius: {}, center: {}".format(self.radius, self.center)
   
     def area(self):
          return 3.14 * self.radius * self.radius
 
my_circle = Circle()
print(my_circle)

خروجی:

radius: 1, center: [0, 0]

وراثت یا ارث بری (inheritance)

وراثت در زبان پایتون مانند هر زبان شی‌گرا دیگر از مفاهیم مهم محسوب می‌شود. وراثت به ما اجازه می‌دهد یک کلاس (کلاس فرزند) ویژگی‌ها و متدهای یک کلاس دیگر (کلاس والد) را به ارث ببرد. همان طور که در دنیای واقعی فرزندان ویژگی‌های والدین خود را به ارث می‌برند در دنیای برنامه‌نویسی نیز کلاس فرزند از کلاس والد ارث‌بری می‌کند.

دستور کلی وراثت در زبان پایتون به شکل زیر است.

class Parent:
    ...
class Child(ParentClass):
    ...

ابتدا کلاس والد و سپس کلاس فرزند تعریف می‌شود و جلوی اسم کلاس فرزند نام کلاس والد ذکر می‌شود. حال کلاس Circle2 را با ارث‌بری از کلاس Circle که در بالا تعریف کردیم تعریف می‌کنیم. کلاس Circle دارای متد area برای محاسبه مساحت دایره است. می‌توانستیم یک متد دیگر برای محاسبه محیط دایره در همین کلاس تعریف کنیم ولی برای آموزش بیشتر این متد را به کلاس Circle2 منتقل کرده‌ایم.

مثال:

class Circle2(Circle):
    def env(self):
        return 2 * 3.14 * self.radius
my_circle = Circle2()
print(my_circle.env())

خروجی:

6.28

همان‌طوری که دیده می‌شود در کلاس Circle2 کاملا به ویژگی‌های کلاس Circle دسترسی داریم. بنابراین کلاس Circle2 دارای دو ویژگی center و radius و دو متد area و env است.