Table of Contents
درک عملی «کلاس» و «شیء» در پایتون
در این بخش فرض میکنیم قبلاً ایدهٔ کلی برنامهنویسی شیگرا را گرفتهاید و اینجا میخواهیم خیلی مشخص ببینیم:
- کلاس در پایتون دقیقاً چیست؟
- شیء (Object) چیست؟
- چطور از روی یک کلاس، شیء میسازیم (مثالش در دنیای واقعی چیست؟)
- چطور با نقطه (
.) به دادهها و رفتارهای یک شیء دسترسی پیدا میکنیم؟ - چند مثال ساده و کاربردی
یادتان باشد اینجا هنوز وارد جزئیات متد __init__، وراثت و … نمیشویم؛ آنها در بخشهای بعدی فصل میآیند.
کلاس به عنوان «الگو» (یا نقشهٔ ساخت)
یک شکل ساده برای فهم کلاس:
- کلاس = نقشه، قالب، طرح
- شیء = نمونهای واقعی که طبق آن نقشه ساخته شده
برای نمونه:
- کلاس
Car= تعریف کلی اینکه «ماشین چیست؟ چه ویژگیهایی دارد؟ چه کارهایی میتواند بکند؟» - شیء
my_carاز کلاسCar= یک ماشین واقعی مشخص (مثلاً یک پژو سفید مدل ۱۳۹۸)
در پایتون، کلاس معمولاً با کلمهٔ کلیدی class تعریف میشود. یک مثال خیلی ساده:
class Dog:
pass
این کد فقط یک کلاس به نام Dog تعریف میکند که فعلاً هیچکاری نمیکند (pass یعنی «فعلاً خالی بمان»).
در اینجا:
Dogنام کلاس است (با حرف بزرگ شروع شده که یک قرارداد رایج است، نه اجبار).- داخل بدنهٔ کلاس (زیر
class Dog:با تورفتگی) بعداً ویژگیها و متدها را تعریف میکنیم.
شیء (Object) چیست؟
وقتی میگوییم «پایتون کاملاً شیگراست»، یعنی خیلی چیزهایی که استفاده میکنید خودشان شیء هستند:
- عدد
5یک شیء است. - رشتهی
"salam"یک شیء است. - لیست
[1, 2, 3]یک شیء است.
هر شیء:
- از روی یک کلاس ساخته شده (حتی اگر شما آن کلاس را مستقیماً ننویسید، پایتون آن را دارد، مثلاً
int،str،listو …). - داده دارد (مثلاً طول رشته، عناصر لیست و …).
- رفتار دارد (مثلاً متد
.append()روی لیست، یا.upper()روی رشته).
ساختن شیء از روی کلاس (نمونهسازی / instantiation)
وقتی یک کلاس خودمان تعریف کنیم، میتوانیم از روی آن، مثل «ساختن یک چیز جدید»، شیء بسازیم. به این کار معمولاً میگوییم:
- نمونهسازی (instantiation)
- ساختن یک نمونه (instance creation)
مثال:
class Dog:
pass
dog1 = Dog()
dog2 = Dog()اینجا:
Dogکلاس است.Dog()یک شیء (نمونه) جدید از این کلاس میسازد.dog1وdog2دو شیء (instance) متفاوت هستند؛ هرچند فعلاً هیچ ویژگی خاصی ندارند.
نکته: Dog (بدون پرانتز) نام کلاس است، Dog() (با پرانتز) یعنی «بساز یک شیء جدید از این کلاس».
تفاوت «کلاس» و «شیء» در نگاه کدنویسی
خلاصهٔ تفاوتها:
- کلاس:
- فقط تعریف است (میگوید این نوع چیزها چه داده و رفتاری میتوانند داشته باشند).
- یک بار نوشته میشود، اما میتوان بینهایت بار از رویش شیء ساخت.
- شیء (instance):
- چیز واقعی ساخته شده از روی کلاس است.
- دادههای خودش را دارد (مثلاً نام، سن، رنگ و …).
- متدهای کلاس را میتواند اجرا کند (رفتار نشان میدهد).
مثال سادهتر:
class Person:
pass
ali = Person()
mina = Person()Person= تعریف کلی یک «شخص»aliوmina= دو شخص واقعی (شیء / instance)
افزودن داده (خصوصیت/ویژگی) به اشیاء
فعلاً بدون ورود به متد __init__، میتوانیم بعد از ساختن شیء، به آن ویژگی اضافه کنیم. این کار بیشتر برای فهم اولیه است، بعدها نحوهٔ اصولیتر را میبینید.
class Person:
pass
person1 = Person()
person2 = Person()
person1.name = "Ali"
person1.age = 20
person2.name = "Sara"
person2.age = 25
print(person1.name, person1.age) # Ali 20
print(person2.name, person2.age) # Sara 25چیزهای مهم در این مثال:
person1.name = "Ali"یعنی روی شیءperson1یک ویژگی به نامnameمیسازیم و به آن مقدار"Ali"میدهیم.person2.nameکاملاً جدا ازperson1.nameاست؛ یعنی هر شیء دادههای خودش را دارد.- دسترسی با علامت نقطه انجام میشود:
- نوشتن/ساختن:
person1.age = 20 - خواندن:
print(person1.age)
این نوع ویژگیها را معمولاً «ویژگی نمونه» یا «Instance Attribute» میگویند؛ یعنی به هر نمونه (شیء) تعلق دارند، نه به کل کلاس به طور مشترک.
مثال: کلاس «کتاب» و اشیاء آن
یک مثال ملموستر:
- میخواهیم با کلاس، یک مفهوم کتاب را مدل کنیم.
- هر کتاب باید مثلاً عنوان (
title) و نویسنده (author) داشته باشد.
class Book:
pass
book1 = Book()
book2 = Book()
book1.title = "یادگیری پایتون"
book1.author = "نویسنده الف"
book2.title = "مقدمات برنامهنویسی"
book2.author = "نویسنده ب"
print(book1.title, "-", book1.author)
print(book2.title, "-", book2.author)خروجی چیزی شبیه این خواهد بود:
یادگیری پایتون - نویسنده الف
مقدمات برنامهنویسی - نویسنده باینجا:
Bookکلاس است (الگو).book1,book2دو شیء از کلاسBookهستند (دو کتاب واقعی مختلف).- هر شیء ویژگیهای خودش را دارد.
نوع (type) اشیاء ساختهشده از کلاس
همانطور که type(5) میشود int، برای شیءهای ساختهشدهی خودمان هم type(...) کلاسشان را نشان میدهد:
class Dog:
pass
dog1 = Dog()
dog2 = Dog()
print(type(dog1))
print(type(dog2))خروجی (تقریباً) چیزی شبیه این خواهد بود:
<class '__main__.Dog'>
<class '__main__.Dog'>- یعنی:
dog1وdog2هر دو «از نوعDog» هستند. - اگر
type(dog1) == Dogرا چک کنید، مقدارشTrueاست:
print(type(dog1) == Dog) # Trueچرا چند شیء از روی یک کلاس مفید است؟
علت اصلی استفاده از کلاس و شیء همین است: تعریف یک الگو، و ساختن چندین نمونه مختلف طبق آن.
مثلاً:
- میخواهید لیست دانشآموزان یک کلاس را نگه دارید.
- هر دانشآموز:
- نام (
name) - سن (
age) - شماره دانشآموزی (
student_id) - و … دارد.
میتوانید:
- یک کلاس
Studentتعریف کنید. - برای هر دانشآموز یک شیء
Studentبسازید. - مثلاً همه را در یک لیست جمع کنید.
نمونه:
class Student:
pass
s1 = Student()
s1.name = "Ali"
s1.age = 16
s2 = Student()
s2.name = "Sara"
s2.age = 17
students = [s1, s2]
for student in students:
print(student.name, "-", student.age)
بعداً در متدها و __init__ خواهید دید چطور میشود این کار را منظمتر و کوتاهتر انجام داد؛ اما در حال حاضر هدف این است که بفهمید:
- «یک کلاس داریم، و چند نمونه از آن میسازیم، و روی هر نمونه بهصورت جداگانه داده ذخیره میکنیم.»
کلاس به عنوان «نوع دادهٔ جدید»
میتوانید کلاس را اینطور هم ببینید:
- در اوایل دوره یاد گرفتید:
int= نوع اعداد صحیحfloat= نوع اعداد اعشاریstr= متن- حالا:
class Person:یعنی شما یک نوع دادهٔ جدید تعریف میکنید.
مثال:
class Person:
pass
p1 = Person()
p2 = Person()
print(isinstance(p1, Person)) # True
print(isinstance(5, Person)) # False
تابع isinstance (که قبلاً با آن آشنا شدهاید یا در فصل توابع/کتابخانهها خواهید دید) بررسی میکند که:
- آیا
p1یک نمونه از کلاسPersonاست؟ - جواب:
True
پس کلاس در واقع نوع (Type) جدیدی تعریف میکند که اشیائش (نمونههایش) از آن نوع هستند.
نامگذاری کلاسها و اشیاء
چند قرارداد ساده و مهم:
- نام کلاسها معمولاً با حرف بزرگ شروع میشوند و اگر چند کلمه باشند، هر کلمه بزرگ آغاز میشود:
Person,Student,BankAccount,Car,ShoppingCart- نام شیءها مثل متغیرها معمولاً با حرف کوچک شروع میشوند:
ali,my_car,account1,cart
این فقط قرارداد است، نه اجبار. ولی رعایت آن:
- کد را خواناتر میکند.
- برای دیگر برنامهنویسان (و حتی خودتان در آینده) خیلی کمککننده است.
تمرکز روی استفادهٔ روزمره: ساختن و استفاده از کلاس ساده
بیایید یک مثال کمی بزرگتر ولی همچنان ساده را ببینیم که در آن:
- یک کلاس
BankAccountتعریف میکنیم. - چند حساب مختلف (شیء) از روی آن میسازیم.
- فعلاً فقط روی ذخیرهٔ داده در سطح شیء تمرکز میکنیم.
class BankAccount:
pass
acc1 = BankAccount()
acc2 = BankAccount()
acc1.owner = "Ali"
acc1.balance = 1000
acc2.owner = "Sara"
acc2.balance = 5000
print("حساب ۱:", acc1.owner, "-", acc1.balance)
print("حساب ۲:", acc2.owner, "-", acc2.balance)چیزی که باید از این مثال در ذهن بماند:
BankAccount= تعریف نوع «حساب بانکی»acc1,acc2= دو حساب بانکی مختلف (دو شیء / instance)- هر حساب:
- صاحب (
owner) مخصوص خودش را دارد. - موجودی (
balance) مخصوص خودش را دارد.
در بخش «ویژگیها و متدها» و «متد __init__» خواهید دید که:
- چطور این ویژگیها را موقع ساخت شیء بهطور منظم مقداردهی کنیم.
- چطور رفتارهایی مثل «واریز»، «برداشت»، «نمایش موجودی» را به شکل متد در کلاس تعریف کنیم.
جمعبندی مفهومی
نکات کلیدی این بخش:
- کلاس یک الگو / نوع دادهٔ جدید / طرح کلی است.
- شیء (instance) یک نمونهٔ واقعی ساخته شده از آن کلاس است.
- از یک کلاس میتوان چندین شیء مختلف با دادههای متفاوت ساخت.
- روی هر شیء، با علامت
.: - میتوانیم ویژگی (Attribute) بسازیم و مقدار بدهیم.
- بعداً متدها را هم صدا میزنیم (در بخشهای بعدی).
- کلاس = تعریف «چه چیزهایی این نوع دارد و چه کارهایی میتواند بکند»،
شیء = «یکی از آن چیزها» با دادههای مشخص خودش.
در ادامهٔ فصل، خواهید دید:
- چطور همین کلاسها را با ویژگیها و متدها کاملتر کنیم.
- چگونه از متد ویژهی
__init__برای مقداردهی اولیهٔ اشیاء استفاده کنیم. - چطور با شیوههای شیگرا، برنامههای منظمتر و قابلگسترشتری بنویسیم.