پایتونمتوسط۶ دقیقه مطالعهPython 3.12+

مبانی شیءگرایی

در این درس کلاس می‌سازید و از آن شیء می‌سازید، متد __init__ و self را می‌فهمید و تصمیم می‌گیرید کجا کلاس و کجا دیکشنری کافی است.

آنچه در این درس می‌آموزید

  • کلاس تعریف کنید و از آن چند شیء بسازید
  • متد __init__ و نقش self را در تعریف و فراخوانی تشخیص دهید
  • تصمیم بگیرید دادهٔ شما کلاس می‌خواهد یا دیکشنری کافی است
نویسنده: تیم داکنامه · بازبینی: ۲۰۲۶-۱۰-۳۰
فهرست مطالب

تا اینجا داده و رفتار جدا بودند: دیکشنری اطلاعات دانش‌آموز را نگه می‌داشت و توابعی جداگانه روی آن کار می‌کردند. شیءگرایی این دو را کنار هم می‌گذارد. کلاس (Class) قالبی است که می‌گوید «این نوع داده چه ویژگی‌هایی دارد و چه کارهایی بلد است»؛ و شیء (Object) نمونه‌ای ساخته‌شده از آن قالب است. هر بار که در این دوره contact = {"name": "سارا"} نوشتید یا text.strip() صدا زدید، در واقع با کلاس و شیء کار کرده‌اید؛ حالا نوبت ساختن آن‌هاست.

کلاس و شیء

کلاس با کلمه کلیدی class تعریف می‌شود و ساختن شیء از آن مثل فراخوانی تابع است:

dog.py
class Dog:
    def bark(self):
        return "Woof woof!"

my_dog = Dog()
print(my_dog.bark())
خروجی کد

Woof woof!

سطر my_dog = Dog() یک شیء تازه از کلاس می‌سازد و my_dog.bark() متد (Method) آن شیء را صدا می‌زند؛ متد یعنی تابعی که به یک شیء وصل است و با نقطه فراخوانی می‌شود، همان نقطه‌ای که در text.strip() دیده بودید.

متد init و ویژگی‌ها

متد ویژهٔ __init__ هنگام ساختن هر شیء به‌طور خودکار اجرا می‌شود و جای مقدارهای اولیه است:

student.py
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def info(self):
        return f"{self.name}: {self.score}"

s = Student("Arash", 18)
print(s.info())
print(s.name)
خروجی کد

Arash: 18 Arash

هنگام Student("آرش", 18) پایتون متد __init__ را صدا می‌زند و آرگومان‌ها به name و score می‌روند. دستور self.name = name ویژگی (Attribute) می‌سازد: داده‌ای که داخل خودِ شیء ذخیره می‌شود و هر جا با نقطه در دسترس است. متد info هم به همین ویژگی‌ها رجوع می‌کند و رشتهٔ مناسب هر شیء را می‌سازد.

نقش self

پارامتر self نشان‌دهندهٔ خودِ همان شیء است که متد رویش صدا زده شده. شما هنگام فراخوانی آن را نمی‌فرستید؛ پایتون خودش می‌فرستد:

  • s.info() در باطن یعنی Student.info(s)؛ شیء s به پارامتر self می‌رود.
  • به همین دلیل تعریف هر متد عادی با self شروع می‌شود، ولی فراخوانی‌اش بدون آرگومان است.

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

هر شیء حالت خودش را دارد

از یک کلاس هر تعداد شیء می‌سازید و هر شیء ویژگی‌های مستقل خودش را دارد:

counter.py
class Counter:
    def __init__(self):
        self.count = 0

    def increase(self):
        self.count += 1

a = Counter()
b = Counter()
a.increase()
a.increase()
b.increase()
print(a.count)
print(b.count)
خروجی کد

2 1

دو شیء a و b هر دو از یک قالب‌اند، ولی شمارندهٔ جدا دارند؛ افزایش a هرگز b را نمی‌لرزاند. متد increase هر بار روی self.count همان شیء کار می‌کند. این جدایی حالت‌ها دلیل اصلی جان گرفتن کلاس است.

متدهایی که تصمیم می‌گیرند

متدها فقط نمایش‌دهندهٔ داده نیستند؛ می‌توانند منطق هم داشته باشند:

grade.py
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def is_passing(self):
        return self.score >= 10

print(Student("Maryam", 17).is_passing())
print(Student("Reza", 8).is_passing())
خروجی کد

True False

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

پایتون خودش شیء را به‌عنوان آرگومان می‌فرستد و اگر متد جای پذیرفتنش نداشته باشد، شکایت می‌کند. :::

کلاس یا دیکشنری؟

دادهٔ سادهٔ بدون رفتار را دیکشنری بگیرید؛ {"name": "سارا", "score": 18} کاملاً شرافتمندانه است. اما هرجا توابعی جداگانه و مکرر روی همان داده کار می‌کنند — اعتبارسنجی، نمایش، مقایسه — کلاس داده و رفتار را یک‌جا جمع می‌کند و برنامه مرتب می‌ماند.

تمرین‌ها

تمرین

تمرین ۱ — کلاس Book

کلاسی به نام Book بنویسید که هنگام ساخت دو ویژگی title و pages بگیرد و متدی به نام summary داشته باشد که رشته‌ای به شکل «کتاب [عنوان] با [تعداد] صفحه» برگرداند؛ سپس یک شیء بسازید و متد را صدا بزنید.

python
# Write your code here
نمایش راه‌حل
python
class Book:
    def __init__(self, title, pages):
        self.title = title
        self.pages = pages

    def summary(self):
        return f"Book {self.title} has {self.pages} pages"

b = Book("Python", 320)
print(b.summary())
خروجی کد

Book Python has 320 pages

::: :::

خلاصه

  • کلاس قالبِ داده و رفتار است و با فراخوانی نامش، از آن شیء ساخته می‌شود.
  • __init__ هنگام ساخت شیء اجرا می‌شود و با self.x = ... ویژگی می‌سازد.
  • self خودِ شیء است؛ فراخوانی s.info() یعنی Student.info(s).
  • هر شیء ویژگی‌های مستقل خودش را دارد؛ تغییر یکی، دیگری را عوض نمی‌کند.
  • دادهٔ بدون رفتار دیکشنری می‌گیرد؛ داده با رفتارِ تکرارشونده کلاس می‌خواهد.

در درس پایانی این دوره، مسیر طی‌شده را مرور می‌کنیم و برای ادامهٔ یادگیری با پروژه‌های واقعی و پکیج‌های عمومی نقشه می‌ریزیم.

منابع و ارجاع‌ها

درس‌های مرتبط