Kahibaro
Discord Login Register

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

تفاوت «ویژگی» و «متد» در کلاس‌ها

در فصل اصلی OOP با مفهوم کلی کلاس و شیء آشنا شده‌اید. در این بخش روی دو جزء مهم هر کلاس تمرکز می‌کنیم:

به صورت شهودی:

مثال: یک شیء از کلاس Car ممکن است:

تعریف ویژگی‌ها در کلاس

ویژگی‌های شیء (ویژگی‌های نمونه، Instance Attributes)

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

برای ایجاد این ویژگی‌ها معمولاً از متد __init__ استفاده می‌کنیم (جزئیات خود __init__ در فصل جداگانه آمده است؛ اینجا فقط استفاده‌اش را برای ویژگی‌ها نشان می‌دهیم):

class Person:
    def __init__(self, name, age):
        self.name = name   # ویژگی شیء
        self.age = age     # ویژگی شیء
p1 = Person("Ali", 20)
p2 = Person("Sara", 25)
print(p1.name, p1.age)  # Ali 20
print(p2.name, p2.age)  # Sara 25

نکات مهم:

p1.age = 21
print(p1.age)  # 21
print(p2.age)  # 25

ویژگی‌های کلاس (Class Attributes) – مقدمه کوتاه

برخی ویژگی‌ها برای همه‌ی اشیاء یکسان هستند؛ این‌ها را معمولاً به صورت مستقیم در بدنه‌ی کلاس تعریف می‌کنیم:

class Person:
    species = "Human"  # ویژگی کلاس - بین همه‌ی اشیاء مشترک است
    def __init__(self, name):
        self.name = name
p1 = Person("Ali")
p2 = Person("Sara")
print(p1.species)  # Human
print(p2.species)  # Human

در این فصل تمرکز اصلی روی تفاوت «ویژگی» و «متد» است؛ تفاوت ویژگی کلاس و ویژگی شیء را در فصل‌های بعدی می‌توان بیشتر گسترش داد. همین‌قدر بدانید:

تعریف متدها در کلاس

متدها در واقع توابعی هستند که داخل کلاس تعریف می‌شوند و معمولاً روی ویژگی‌های همان شیء کار می‌کنند.

ساختار کلی:

class ClassName:
    def method_name(self, other_parameters):
        # کاری انجام بده
        ...

نکته‌ی مهم: اولین پارامتر متدهای نمونه تقریباً همیشه self است.

یک مثال ساده از متد

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def say_hello(self):
        print(f"سلام! من {self.name} هستم و {self.age} سالمه.")
p = Person("Ali", 20)
p.say_hello()
# خروجی: سلام! من Ali هستم و 20 سالمه.

این‌جا:

چرا باید از `self` استفاده کنیم؟

پس:

کار با ویژگی‌ها در متدها

متدها معمولاً سه کار اصلی با ویژگی‌ها انجام می‌دهند:

  1. خواندن مقدار ویژگی‌ها
  2. تغییر دادن مقدار ویژگی‌ها
  3. استفاده‌ی ترکیبی از چند ویژگی برای یک محاسبه

مثال: تغییر ویژگی در متد

class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner
        self.balance = balance  # موجودی
    def deposit(self, amount):
        self.balance += amount  # افزایش موجودی
    def withdraw(self, amount):
        self.balance -= amount  # کاهش موجودی
    def show_balance(self):
        print(f"موجودی حساب {self.owner}: {self.balance} تومان")
acc = BankAccount("Ali", 1000)
acc.deposit(500)       # واریز
acc.withdraw(200)      # برداشت
acc.show_balance()     # موجودی حساب Ali: 1300 تومان

در این مثال:

متدهایی با پارامتر

همان‌طور که توابع معمولی پارامتر می‌گیرند، متدها هم علاوه بر self می‌توانند پارامتر داشته باشند.

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def resize(self, new_width, new_height):
        self.width = new_width
        self.height = new_height
    def area(self):
        return self.width * self.height
rect = Rectangle(2, 3)
print(rect.area())  # 6
rect.resize(5, 4)
print(rect.area())  # 20

متدها در مقابل توابع عادی

تابع عادی:

متد:

مقایسه:

# تابع عادی
def full_name(first, last):
    return first + " " + last
# کلاس با متد
class Person:
    def __init__(self, first, last):
        self.first = first
        self.last = last
    def full_name(self):
        return self.first + " " + self.last

در تابع عادی:

در متد:

تغییر و اضافه‌کردن ویژگی به صورت پویا

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

تغییر ویژگی موجود

class Person:
    def __init__(self, name):
        self.name = name
p = Person("Ali")
print(p.name)  # Ali
p.name = "Reza"
print(p.name)  # Reza

اضافه‌کردن ویژگی جدید بیرون از کلاس

class Person:
    def __init__(self, name):
        self.name = name
p = Person("Ali")
p.age = 20   # تعریف یک ویژگی جدید به صورت پویا
print(p.name, p.age)  # Ali 20

این انعطاف‌پذیری بالاست، ولی برای کدهای بزرگ‌تر بهتر است ویژگی‌های اصلی را در __init__ تعریف کنید تا ساختار شیء قابل پیش‌بینی باشد.

متدهای نمونه در مقابل متدهای کلاس و استاتیک (نگاه مقدماتی)

به طور کلی سه نوع متد وجود دارد (در این فصل فقط نوع اول را جدی استفاده می‌کنیم):

  1. متد نمونه (Instance Method)
    • رایج‌ترین نوع؛ متدی که اولین پارامترش self است.
    • روی یک شیء خاص کار می‌کند و به ویژگی‌های آن دسترسی دارد.
  2. متد کلاس (Class Method)
    • معمولاً با دکوراتور @classmethod مشخص می‌شود و اولین پارامترش cls است.
    • روی خود کلاس کار می‌کند، نه روی یک شیء خاص.
  3. متد استاتیک (Static Method)
    • با @staticmethod مشخص می‌شود.
    • مثل یک تابع عادی است که فقط برای نظم‌دهی داخل کلاس قرار گرفته.

در این فصل هدف‌تان این است که:

چند الگوی متداول برای متدها

متد «نمایشی» (`show`، `info` و …)

متدی که اطلاعات شیء را چاپ می‌کند:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def info(self):
        print(f"نام: {self.name}, سن: {self.age}")
p = Person("Sara", 30)
p.info()

متد «تغییر حالت» (state-changing)

متدی که وضعیت شیء را عوض می‌کند:

class Light:
    def __init__(self):
        self.is_on = False
    def turn_on(self):
        self.is_on = True
    def turn_off(self):
        self.is_on = False
lamp = Light()
lamp.turn_on()
print(lamp.is_on)  # True

متد «محاسباتی» با مقدار بازگشتی

متدی که بر اساس ویژگی‌ها چیزی محاسبه می‌کند و برمی‌گرداند (چاپ نمی‌کند):

class Circle:
    def __init__(self, radius):
        self.radius = radius
    def area(self):
        pi = 3.14159
        return pi * (self.radius ** 2)
c = Circle(10)
result = c.area()
print(result)

توجه کنید:

تمرین‌های پیشنهادی

برای تمرینِ ویژگی‌ها و متدها، می‌توانید این ایده‌ها را پیاده کنید:

  1. کلاس Student
    • ویژگی‌ها: name، grade (نمره)
    • متدها:
      • show_info() برای چاپ نام و نمره
      • is_passed() که اگر نمره بالای ۱۰ بود True برگرداند وگرنه False.
  2. کلاس Dog
    • ویژگی‌ها: name، age
    • متدها:
      • bark() که یک جمله مثل "Woof! من Rex هستم" چاپ کند.
      • get_human_age() که سن سگ را مثلا در ۷ ضرب کند و مقدار را برگرداند.
  3. کلاس Counter
    • ویژگی: value
    • متدها:
      • increment() که مقدار را یک واحد زیاد کند.
      • reset() که مقدار را صفر کند.
      • show() که مقدار فعلی را چاپ کند.

در این تمرین‌ها تلاش کنید:

Views: 7

Comments

Please login to add a comment.

Don't have an account? Register now!