برنامه نویسی و طراحی سایت

شی گرایی در پایتون چیست؟ – به زبان ساده + مثال و تمرین

شی گرایی در پایتون چیست؟ – به زبان ساده + مثال و تمرین

«شی گرایی» یا «برنامه نویسی شی گرا» (Object-Oriented Programming | OOP) یکی از رویکردهای مهم در برنامه نویسی است که بسیاری از برنامه‌نویسان با استفاده از این رویکرد به توسعه پروژه‌های خود می‌پردازند. این شیوه شامل مفاهیم کلیدی و اصول خاصی می‌شود که باید از آن‌ها در پیاده‌سازی برنامه‌های مبتنی بر این روش استفاده شود. زبان برنامه نویسی پایتون از جمله محبوب‌ترین و پرکاربردترین زبان‌های برنامه نویسی به حساب می‌آید که شی‌گرا هم هست و به خوبی می‌توان اصول شی‌گرایی را در آن پیاده‌سازی کرد. بنابراین در مطلب حاضر، سعی بر این است به شی گرایی در پایتون بپردازیم و مثال‌های کاربردی را از این زبان ارائه کنیم تا مخاطبان با رویکرد برنامه نویسی شی گرا در پایتون آشنا شوند.

فهرست مطالب این نوشته
شی گرایی در پایتون چیست ؟

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

نحوه تعریف کلاس و شی در پایتون

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

متغیر کلاس در پایتون چیست ؟

متغیرهای وحله ای در کلاس های پایتون

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

متد وحله ای در کلاس پایتون چیست ؟

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

اصول شی گرایی در پایتون

اصل وراثت شی گرایی در پایتون چیست ؟

وراثت منفرد در پایتون

وراثت چندگانه شی گرایی در پایتون چیست ؟

وراثت چندسطحی در شی گرایی در پایتون چیست ؟

وراثت سلسله مراتبی شی گرایی در پایتون چیست ؟

وراثت ترکیبی در پایتون

اصل کپسوله سازی شی گرایی در پایتون چیست ؟

مشخصه های عمومی کلاس در پایتون

مشخصه های محافظت شده کلاس در پایتون

مشخصه های خصوصی کلاس در پایتون

اصل انتزاع شی گرایی در پایتون

اصل چندریختی در پایتون

مدیریت ویژگی در کلاس های پایتون

تمرین برنامه نویسی شی گرا با زبان پایتون

تمرین ۱. تعریف کلاس در پایتون

پاسخ تمرین ۱

تمرین ۲. تعریف مشخصه های کلاس و شی در پایتون

پاسخ تمرین ۲

تمرین ۳. ارث بری در پایتون

پاسخ تمرین ۳

تمرین ۴. باز نویسی متد در کلاس پایتون

پاسخ تمرین ۴

تمرین ۵. متغیرهای کلاس در پایتون

پاسخ تمرین ۵

تمرین ۶. بررسی رابطه والد و فرزندی بین کلاس ها

پاسخ تمرین ۶

جمع‌بندی

faradars mobile

شی گرایی در پایتون چیست ؟

رویکرد برنامه نویسی شی گرا، بر پایه دو مفهوم اصلی «شی» (Object) و «کلاس» (Class) شکل گرفته است که با این دو مفهوم می‌توان اطلاعات تمام «ماهیت‌های» (Entity) دنیای واقعی را در برنامه به راحتی ذخیره کرد.

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

به بیان جزئی‌تر می‌توان گفت هدف از شی گرایی در پایتون ساخت کلاسی است که دربرگیرنده تمامی «ویژگی‌ها» (Properties) و «رفتارها | متدهای» (Methods) مرتبط با یک ماهیت باشد و از طریق ایجاد شی از کلاس مربوطه بتوان به همه «مشخصه‌ها» (Attributes) یا همان ویژگی‌ها و متدها دسترسی داشت.

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

مثال شی گرایی در پایتون چیست

شی گرایی علاوه بر مفاهیم شی و کلاس دارای اصول مهمی هم هست که پیاده‌سازی برنامه‌های مبتنی بر شی گرایی باید با درک و شناخت این اصول انجام شود. در ادامه مطلب، به توضیح جزئی‌تری از مفاهیم و اصول شی گرایی خواهیم پرداخت و مثال‌های کاربردی از زبان برنامه نویسی پایتون برای هر یک از آن‌ها ارائه خواهد شد.

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

انواع داده‌های پایتون نظیر اعداد، رشته‌ها و لیست‌ها به منظور ذخیره مقادیر ساده‌ای از اطلاعات ایجاد شده‌اند. به عنوان مثال، با تعریف متغیرهایی با نام‌های Price و ColorName از نوع عددی و رشته‌ای، می‌توان به ترتیب، قیمت یک سیب و رنگ آن را ذخیره کرد.

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

حال فرض کنید قصد دارید با اطلاعات پیچیده‌تری در برنامه نویسی کار کنید. به عنوان مثال، مدیر شرکت از شما می‌خواهد اطلاعات شخصی کارمندان را در یک فایل ذخیره کنید. این اطلاعات می‌تواند شامل نام کارمندان، سن، سِمَت شغلی و تاریخ شروع به کار آن‌ها باشد.

یکی از روش‌های ذخیره‌سازی چنین اطلاعاتی در زبان پایتون این است که از ساختار داده لیست استفاده شود و برای هر کارمند در سازمان، لیستی از اطلاعات شخصی بسازید. مثال زیر، اطلاعات سه کارمند را نشان می‌دهد که با استفاده از ساختار داده لیست در سه متغیر جداگانه ذخیره شده‌اند:

kirk = ["James Kirk", 34, "Captain", 2265]
spock = ["Spock", 35, "Science Officer", 2254]
mccoy = ["Leonard McCoy", "Chief Medical Officer", 2266]

با این که چنین روشی برای ذخیره اطلاعات کارمندان، ساده است، اما مشکلات مهمی دارد. چنانچه بخواهید به اطلاعات هر شخص در برنامه دسترسی داشته باشید، باید از اندیس استفاده شود. به عنوان مثال، اندیس صفر از لیست kirk

 ، نام کارمند را مشخص می‌کند.

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

آموزش کلاس در پایتون (رایگان)
فیلم آموزش کلاس در پایتون (رایگان) در تم آف

کلیک کنید

به علاوه، چنانچه اطلاعات کارمندان کامل نباشد، طول لیست‌های تعریف شده برای هر یک از کارمندان یکسان نخواهد بود و شماره اندیس‌های مشابه تمامی لیست‌ها، به اطلاعات یکسانی اشاره نخواهند داشت. در مثالی که ارائه کردیم، اندیس ۱ در لیست‌های kirk

و spock

به سن ۲ کارمند اشاره دارد، اما در لیست mccoy

، آیتمی برای سن کارمند لحاظ نشده است و اندیس ۱ از این لیست، عنوان شغلی کارمند را نشان می‌دهد.

برای رفع چنین مشکلات مهمی، می‌توان از شی گرایی در پایتون استفاده کرد و اطلاعات کلیه کارمندان را با تعریف یک کلاس و ساخت اشیای مختلف برای هر یک از کارمندان در برنامه ذخیره کرد.

مفاهیم کلاس و شی در شی گرایی پایتون

به عبارتی می‌توان گفت شی گرایی در پایتون این امکان را فراهم می‌کند تا با استفاده از کلاس، بتوان ساختار داده جدیدی را تعریف کرد و برای آن ویژگی‌ها و متدهای مختلفی در نظر گرفت. کلاس، طرح اولیه‌ای از هر ماهیت است و داده‌ای را در خود ذخیره نمی‌کند. به منظور ذخیره کردن داده‌ها با استفاده از کلاس، باید «نمونه‌ای» (وحله | Instance) از کلاس ساخته شود تا بتوان داده‌های خود را در آن ذخیره کرد. به هر نمونه ایجاد شده از کلاس، شی گفته می‌شود. در واقع کلاس «نقشه ساخت» شی به حساب می‌آید.

در مثالی که برای ذخیره اطلاعات کارمندان ارائه کردیم، می‌توان کلاسی را با نام Person ایجاد کرد که درون این کلاس می‌توان ویژگی‌های مربوط به کارمندان مانند اسم، سن، آدرس، سمت شغلی و تاریخ شروع به کار را تعریف کرد. همچنین عملیات و توابعی که اشیای کلاس کارمند می‌توانند پیاده‌سازی کنند را نیز مِتُدهای کلاس می‌نامند و این متدها در واقع رفتار اشیای مشتق شده از کلاس را مشخص می‌کنند. سپس، به منظور ذخیره داده‌های هر یک از کارمندان، باید از شی استفاده کرد. در ادامه، به نحوه ساخت کلاس و شی در زبان برنامه نویسی پایتون پرداخته می‌شود.

نحوه تعریف کلاس و شی در پایتون

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

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

به منظور تعریف کلاس در پایتون، از کلمه کلیدی class

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

 ) پس از نام کلاس قرار می‌گیرد. در ادامه، مثالی از نحوه ساخت کلاس برای کلاس Person

ملاحظه می‌شود.

class Person:
    pass

چنانچه نام کلاس از چندین کلمه تشکیل شده باشد، باید کلمات بدون درج فاصله به گونه‌ای نوشته شوند که حروف نخست کلمات، حروف بزرگ انگلیسی باشند. به عنوان مثال، اگر قصد دارید کلاسی برای کارمندان بخش فروش سازمان بسازید، می‌توانید از نام SalesEmployee

 استفاده کنید.

از کلمه کلیدی pass

 در توابع و کلاس‌هایی استفاده می‌شود که دستورات در بدنه آن‌ها نوشته نشده باشند. نوشتن این کلمه کلیدی باعث می‌شود در زمان اجرای برنامه، خطای کامپایلر رخ ندهد. پس از ساخت کلاس، می‌توان شیئی را به عنوان وحله‌ای از کلاس ساخت. در بخش پیشین، از متغیری با عنوان kirk

برای ذخیره اطلاعات یکی از کارمندان استفاده کردیم. از همین نام برای ساخت یک شی جدید از کلاس Person

به روش زیر استفاده می‌کنیم:

class Person:
    pass

kirk = Person()

چنانچه کلاس Person

دارای ویژگی‌ها و متدهای مختلف باشد، با استفاده از شی kirk

می‌توان به هر یک از آن‌ها دسترسی داشت و اطلاعات کارمند kirk

را با استفاده از ویژگی‌ها و متد کلاس Person

ذخیره کرد. با استفاده از دستور type()

 نیز می‌توان کلاس شی تعریف شده را مشخص کرد. در مثال زیر، نحوه کاربرد این تابع ارائه شده است:

print(type(kirk))

خروجی قطعه کد بالا به صورت

  است که این خروجی نشان می‌دهد شی kirk

به عنوان نمونه‌ای از کلاس Person

محسوب می‌شود. پس از ساخت کلاس Person

و تعریف شی از این کلاس، می‌توان با استفاده از تابع isinstance()

مشخص کرد که آیا شی، نمونه‌ای از کلاس Person

است؟ قطعه کد زیر، نحوه استفاده از این تابع را نشان می‌دهد.

kirk = Person()
print(isinstance(kirk, Person))  # True

خروجی قطعه کد بالا برابر با True‌ است که این مقدار نشان می‌دهد شی kirk

، نمونه‌ای از کلاس Person

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

مطلب پیشنهادی:

کلاس در پایتون چیست ؟ — آموزش کامل ساخت و استفاده + کد و مثال

شروع مطالعه

 

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

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

آموزش برنامه نویسی پایتون Python – مقدماتی
فیلم آموزش برنامه نویسی پایتون Python – مقدماتی در تم آف

کلیک کنید

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

  • «متغیرهای کلاس» (Class Variables)
  • «متغیرهای وحله‌ای» (Instance Variables)

در ادامه مطلب، به توضیح هر یک از این دو نوع متغیر و نحوه ساخت آن‌ها در پایتون پرداخته می‌شود.

متغیر کلاس در پایتون چیست ؟

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

آموزش برنامه نویسی پایتون + مثال های عملی در Python
فیلم آموزش برنامه نویسی پایتون + مثال های عملی در Python در تم آف

کلیک کنید

در قطعه کد زیر، متغیر‌های extension

 و version

 مثال‌هایی از متغیرهای کلاس HtmlDocument

 هستند.

class HtmlDocument:
    extension = 'html'
    version = '5'

به منظور دسترسی به مقادیر متغیرهای کلاس، می‌توان از نام کلاس HtmlDocument

به همراه علامت نقطه ( .

 ) و سپس نام متغیر کلاس استفاده کرد.

class HtmlDocument:
    extension = 'html'
    version = '5'

print(HtmlDocument.extension) # html
print(HtmlDocument.version) # 5

همچنین، می‌توان شیئی از کلاس HtmlDocument

ساخت و با استفاده از نام شی به متغیرهای کلاس دسترسی داشت.

class HtmlDocument: 
    extension = 'html' 
    version = '5' 

object = HtmlDocument() 
print(object.extension) # html 
print(object.version) # 5

چنانچه، نام متغیر کلاسی را به اشتباه فراخوانی کنیم و آن متغیر در کلاس تعریف نشده باشد، خطای کامپایلر رخ می‌دهد.

class HtmlDocument: 
extension = 'html' 
version = '5' 

print(HtmlDocument.media_type) 

در قطعه کد بالا، متغیر medi_TYPE

در کلاس HtmlDocument

تعریف نشده است. به همین خاطر، در زمان اجرای قطعه کد بالا، خطای زیر رخ می‌دهد:

AttributeError: type object 'HtmlDocument' has no attribute 'media_type'

روش دیگری که می‌توان از طریق آن به متغیرهای کلاس دسترسی داشت، استفاده از تابع getattr()

است. این تابع،‌ نام شی و نام متغیر کلاس را به عنوان ورودی دریافت می‌کند و مقدار متغیر کلاس را به عنوان خروجی بازمی‌گرداند. در قطعه کد زیر، نحوه استفاده از این تابع نشان داده شده است.

class HtmlDocument:
    extension = 'html'
    version = '5'

extension = getattr(HtmlDocument, 'extension')
version = getattr(HtmlDocument, 'version')

print(extension)  # html
print(version)  # 5

به منظور تغییر مقادیر متغیرهای کلاس می‌توان از نام کلاس و نام شی به روش زیر استفاده کرد:

HtmlDocument.version = 10
object.version = 10

به علاوه،‌ تابع setattr()

را نیز می‌توان برای تغییر مقادیر متغیرهای کلاس به کار برد. در قطعه کد زیر، نحوه استفاده از این تابع نشان داده شده است.

setattr(HtmlDocument, 'version', 10)

به منظور اضافه کردن متغیرهای کلاس جدید می‌توان از سه روش استفاده کرد. روش اول، اضافه کردن نام متغیر کلاس به همراه مقدار آن درون کلاس تعریف شده است. در روش دوم، می‌توان از بیرون کلاس، متغیر کلاس جدیدی را به کلاس تعریف شده از قبل، به روش زیر اضافه کرد:

HtmlDocument.media_type = 'text/html'
print(HtmlDocument.media_type) # text/html

روش سوم برای اضافه کردن متغیر کلاس جدید به کلاس از پیش تعریف شده، استفاده از تابع setattr()

است. در قطعه کد زیر، نحوه استفاده از این تابع نشان داده شده است:

setattr(HtmlDocument, media_type, 'text/html')
print(HtmlDocument.media_type) # text/html

شی گرایی در پایتون این امکان را به برنامه‌نویسان می‌دهد تا وقتی به متغیر کلاسی احتیاج نداشتند، آن متغیر را با استفاده از تابع delattr()

و کلمه کلیدی del

از برنامه حذف کنند. در قطعه کد زیر، نحوه استفاده از این دو روش برای حذف متغیرهای کلاس HtmlDocument

ملاحظه می‌شود.

delattr(HtmlDocument, 'version')
del HtmlDocument.extension

متغیرهای وحله ای در کلاس های پایتون

متغیرهای نمونه، متغیرهایی هستند که درون توابع (متدها) و «سازنده‌ها» (Constructors) تعریف می‌شوند. مقادیر این متغیرها برای هر یک از اشیای ساخته شده از یک کلاس مشابه، متفاوت هستند.

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

به عبارتی، این نوع متغیرها مختص اشیاء هستند و مقادیرشان بین اشیاء مختلف کلاس به اشتراک گذاشته نمی‌شوند. به منظور مقداردهی اولیه متغیرهای نمونه، می‌توان از متد __init__()

درون کلاس استفاده کرد. زمانی که شی جدیدی را از یک کلاس ایجاد می‌کنید، به‌طور خودکار، متد __init__()

فراخوانی می‌شود. بدین ترتیب، می‌توان از این متد برای مقداردهی اولیه مشخصه‌های اشیاء استفاده کرد. در قطعه کد زیر، مثالی از نحوه مقداردهی اولیه متغیرهای نمونه در کلاس Person

ملاحظه می‌شود.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

object_person = Person('John', 25)
print(f"I'm {object_person.name}. I'm {object_person.age} years old.")

در مثال بالا، متغیرهای name

و Page

متغیرهای نمونه از کلاس Person

هستند و به هنگام ساخت شی object_person

، تابع __init__()

فراخوانی می‌شود و مقادیر John

و 25

درون متغیرهای نمونه name

و age

قرار می‌گیرند. همان‌طور که در این مثال ملاحظه می‌کنید، نخستین پارامتر تابع __init__()

، مقدار self

است. در زبان برنامه نویسی پایتون، زمانی که با استفاده از نام شی، تابعی (متدی) را فراخوانی می‌کنیم، به‌طور خودکار، خود شی به عنوان اولین پارامتر، به آن تابع ارسال می‌شود.

بنابراین، دستور Person(‘John’,25)

در قطعه کد بالا، معادل دستور Person(object_person, ‘John’,25)

است. به همین دلیل، اولین پارامتر تابع درون کلاس، باید پارامتر self

باشد که به شی فعلی کلاس اشاره دارد. می‌توان نام self

را تغییر داد، اما به منظور فهم دقیق‌تر کدها و پایبند بودن به قراردادهای زبان پایتون، بهتر است که از همین کلمه کلیدی برای اشاره به شی استفاده شود. خروجی قطعه کد بالا در ادامه ملاحظه می‌شود:

I'm John. I'm 22 years old.

در تصویر زیر نیز مثالی برای متغیرهای نمونه یا همان متغیرهای وحله‌ای در شی گرایی پایتون ارائه شده است.

متغیرهای نمونه در کلاس پایتون

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

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

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

انواع متدهای درون کلاس به شرح زیر هستند:

  • «متد وحله‌ای» (Instance Method)
  • «متد کلاس» (Class Method)

در ادامه این مطلب، به توضیح انواع متدهای کلاس پایتون به همراه مثال‌های کاربردی پرداخته شده است.

متد وحله ای در کلاس پایتون چیست ؟

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

آموزش آشنایی با مفاهیم اولیه شی گرایی در پایتون (رایگان)
فیلم آموزش آشنایی با مفاهیم اولیه شی گرایی در پایتون (رایگان) در تم آف

کلیک کنید

اولین آرگومان دریافتی این متدها، عبارت self

است که به شی اشاره دارد. در ادامه، قطعه کدی ملاحظه می‌شود که نحوه تعریف متد نمونه کلاس را نشان می‌دهد.

class Request:
    def send(self):
        print('Sent')

http_request = Request()
print(http_request.send()) # Sent

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

با استفاده از شی گرایی در پایتون می‌توان متدهایی از نوع متد کلاس تعریف کرد که از طریق آن‌ها می‌توان مقادیر متغیرهای کلاس را تغییر داد. همان‌طور که در بخش مربوط به متغیر کلاس توضیح داده شد، مقادیر این نوع متغیرها برای تمامی اشیاء ساخته شده از یک کلاس مشابه، به اشتراک گذاشته می‌شوند.

آموزش برنامه نویسی پایتون Python – مقدماتی
فیلم آموزش برنامه نویسی پایتون Python – مقدماتی در تم آف

کلیک کنید

متدهای کلاس را می‌توان به دو روش در پایتون ایجاد کرد. در اولین روش، از «دکوراتوری» (Decorator) با نام @classmethod

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

from datetime import date

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def calculate_age(cls, name, birth_year):
        # calculate age an set it as a age
        # return new object
        return cls(name, date.today().year - birth_year)

    def show(self):
        print(self.name + "'s age is: " + str(self.age))


# create new object using the factory method
joy = Student.calculate_age("Joy", 1995)
joy.show()

در مثال بالا، متد calculate_age

از نوع متد کلاس است. خاطر نشان می‌شود نخستین پارامتر متد کلاس باید مقدار cls

باشد که به نام کلاس جاری اشاره می‌کند.

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

روش دیگری که با کمک آن می‌توان متد کلاس تعریف کرد، استفاده از تابع classmethod

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

در نظر گرفت تا این تابع، متد مشخص شده را به متد کلاس تبدیل کند. در قطعه کد زیر، مثالی از کاربرد تابع classmethod

برای ساخت متد کلاس school_name

ملاحظه می‌شود.

class School:
    # class variable
    name = 'ABC School'

    def school_name(cls):
        print('School Name is :', cls.name)

# create class method
School.school_name = classmethod(School.school_name)

# call class method
School.school_name()

اصول شی گرایی در پایتون

برنامه نویسی شی گرا علاوه بر مفاهیم شی و کلاس، شامل چهار اصل مهم هم هست که با لحاظ کردن این اصول در توسعه پروژه‌های نرم‌افزاری، میزان بهره‌وری برنامه‌ها بیشتر می‌شود و برنامه‌نویسان می‌توانند به راحتی، قطعه کدهای نوشته شده را به‌روزرسانی و آن‌ها را گسترده‌تر کنند.

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

همچنین، با رعایت اصول شی گرایی می‌توان سطح امنیت برنامه نویسی را بالا برد و کدها را به صورت ماژولار نوشت که همین امر باعث می‌شود میزان خوانایی برنامه‌ها بیشتر شود و بتوان به آسانی، از قطعه کدهای نوشته شده در سایر پروژه‌های نرم‌افزاری به دفعات استفاده کرد. چهار اصل مهم شی گرایی در پایتون و در سایر زبان‌های برنامه نویسی شی گرا در ادامه فهرست شده‌اند:

  • اصل «کپسوله‌سازی» (Encapsulation)
  • اصل «انتزاع | تجرید» (Abstraction)
  • «وراثت | ارث‌بری» (Inheritance)
  • «پلی مورفیسم | چندریختی» (Polymorphism)

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

مطلب پیشنهادی:

اصول برنامه نویسی شی گرا — به زبان ساده

شروع مطالعه

اصل وراثت شی گرایی در پایتون چیست ؟

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

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

کلاس فرزند می‌تواند ویژگی‌ها و متدهایی را که از کلاس والد به ارث برده است، بنا به نیاز خود تغییر دهد. چنانچه بخواهیم مثال قابل درکی از دنیای واقعی برای اصل وراثت ارائه دهیم، می‌توان به ژن‌های پدر و مادر و انتقال آن‌ها به فرزندانشان اشاره کرد.

ممکن است فرزند رنگ موی خود را از مادرش به ارث ببرد. با این حال، فرزند تصمیم می‌گیرد رنگ موی خود را تغییر دهد و موی خود را به رنگ صورتی تغییر دهد. با اینکه فرزند، داشتن ویژگی رنگ مو را از پدر و مادر خود به ارث برده است، اما می‌تواند به تصمیم خود، رنگ آن را تغییر دهد و موی خود را به رنگی درآورد که مشابه رنگ موی پدر و مادر خود نیست.

اصل وراثت در شی گرایی در پایتون چیست

شی گرایی در پایتون نیز بر اساس تعاریفی که از وراثت و نحوه ارث‌بری در دنیای حقیقی وجود دارد، این امکان را به برنامه نویس می‌دهد تا از کلاسی که ساخته شده است، بتوان به دفعات مختلف به شیوه‌ای استفاده کرد که مشخصه‌های کلاس، مطابق نیاز کاربر تغییر کنند. به منظور درک بهتر این اصل، مثالی از پایتون ارائه می‌کنیم.

فرض کنید کلاسی با نام Person

ساخته شده است که مشخصه‌های __init__

و greet

را دارد. در قطعه کد زیر، مثالی از این کلاس ملاحظه می‌شود.

class Person:
    def __init__(self, name):
        self.name = name

    def greet(self):
        return f"Hi, it's {self.name}"

حال می‌خواهیم کلاسی با نام Employee

ایجاد کنیم که دقیقاً مشخصه‌های کلاس Person

را داشته باشد. در قطعه کد زیر، نحوه ساخت کلاس Person

ملاحظه می‌شود.

class Employee:
    def __init__(self, name, job_title):
        self.name = name
        self.job_title = job_title

    def greet(self):
        return f"Hi, it's {self.name}"

همان‌طور که در قطعه آمده است، کلاس Employee

دارای متد greet

است که همین متد در کلاس Person

نیز وجود دارد. با استفاده از اصل وراثت در شی گرایی پایتون، می‌توان متد greet

را از کلاس Employee

حذف کرد و با ایجاد ارتباط بین دو کلاس Employee

و Person

، متد greet

را از کلاس Person

به ارث برد. در این حالت، کلاس Employee

به عنوان کلاس فرزند و کلاس Person

به عنوان کلاس والد مشخص می‌شوند. در ادامه، نحوه به‌کارگیری اصل وراثت در پایتون ملاحظه می‌شود.

class Employee(Person):
    def __init__(self, name, job_title):
        self.name = name
        self.job_title = job_title

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

علاوه بر ویژگی‌های name

و job_title

، دارای متد greet

نیز هست که آن را از کلاس والد خود، یعنی کلاس Person

، به ارث می‌برد. در ادامه، مثالی از نحوه دسترسی به متد greet

از طریق شی ساخته شده از کلاس Employee

ملاحظه می‌شود.

employee = Employee('John', 'Python Developer')
print(employee.greet())

خروجی قطعه کد بالا در ادامه نشان داده شده است:

Hi, it's John

با استفاده از تابع issubclass()

می‌توان مشخص کرد که آیا دو کلاس رابطه والد – فرزندی دارند؟ در ادامه، نحوه استفاده از این تابع در زبان پایتون در قالب مثال، نشان داده شده است:

print(issubclass(Employee, Person)) # True

همچنین، با استفاده از super()

می‌توان از داخل کلاس فرزند، به متدهای کلاس والد دسترسی داست. در ادامه، قطعه کدی از زبان پایتون ارائه شده است که نحوه استفاده از super()

را نشان می‌دهد.

class Employee:
    def __init__(self, name, base_pay, bonus):
        self.name = name
        self.base_pay = base_pay
        self.bonus = bonus

    def get_pay(self):
        return self.base_pay + self.bonus


class SalesEmployee(Employee):
    def __init__(self, name, base_pay, bonus, sales_incentive):
        super().__init__(name, base_pay, bonus)
        self.sales_incentive = sales_incentive

    def get_pay(self):
        return super().get_pay() + self.sales_incentive


if __name__ == '__main__':
    sales_employee = SalesEmployee('John', 5000, 1000, 2000)
    print(sales_employee.get_pay())  # 8000

اصل وراثت می‌تواند از راه‌های مختلف در برنامه نویسی استفاده شود. به عبارتی، انواع مختلفی از ارث‌بری در شی گرایی وجود دارد که در ادامه به آن‌ها اشاره شده است.

  • «وراثت منفرد» (Single Inheritance)
  • «وراثت چندگانه» (Multiple Inheritance)
  • «وراثت چند سطحی» (Multi-Level Inheritance)
  • «وراثت سلسله‌مراتبی» (Hierarchical Inheritance)
  • «وراثت ترکیبی» (Hybrid Inheritance)
انواع ارث بری در شی گرایی در پایتون چیست
انواع ارث بری در شی گرایی

در ادامه مطلب حاضر، به توضیح هر یک از انواع وراثت پرداخته می‌شود و مثالی کاربردی از زبان پایتون برای هر یک از آن‌ها ارائه خواهد شد.

وراثت منفرد در پایتون

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

#syntax_of_single_inheritance

class class1:               #parent_class
    pass

class class2(class1):       #child_class
    pass

obj_name = class2()
نوع ارث‌بری مثالی که در بخش پیشین درباره دو کلاس Employee

و Person

ارائه شد، از نوع وراثت منفرد است.

وراثت چندگانه شی گرایی در پایتون چیست ؟

زمانی که چندین کلاس وجود داشته باشند و بخواهیم کلاس جدیدی را به عنوان کلاس فرزند ایجاد کنیم که تمامی مشخصه‌های کلاس‌های موجود را به ارث ببرد، از وراثت چندگانه استفاده می‌کنیم.

آموزش برنامه نویسی پایتون ویژه نوجوانان – بخش یکم
فیلم آموزش برنامه نویسی پایتون ویژه نوجوانان – بخش یکم در تم آف

کلیک کنید

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

#syntax_of_multiple_inheritance

class parent_1:
    pass

class parent_2:
    pass

class child(parent_1,parent_2):
    pass

obj = child()

مثال زیر نیز، قطعه کدی از زبان پایتون را نشان می‌دهد که در آن دو کلاس والد با نام‌های Brands

و Products

ساخته شده‌اند و کلاس فرزندی نیز با نام Popularity

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

#example_of_multiple_inheritance

class Brands:               #parent_class
    brand_name_1 = "Amazon"
    brand_name_2 = "Ebay"
    brand_name_3 = "OLX"
    
class Products:            #child_class
    prod_1 = "Online Ecommerce Store"
    prod_2 = "Online Store"
    prod_3 = "Online Buy Sell Store"

class Popularity(Brands,Products):
    prod_1_popularity = 100
    prod_2_popularity = 70
    prod_3_popularity = 60
    
obj_1 = Popularity()          #Object_creation
print(obj_1.brand_name_1+" is an "+obj_1.prod_1))
print(obj_1.brand_name_2+" is an "+obj_1.prod_2))
print(obj_1.brand_name_3+" is an "+obj_1.prod_3))

خروجی قطعه کد بالا، در ادامه ملاحظه می‌شود.

#Output
#Amazon is an Online Ecommerce Store popularity of 100
#Ebay is an Online Store popularity of 70
#OLX is an Online Buy Sell Store popularity of 60

وراثت چندسطحی در شی گرایی در پایتون چیست ؟

وراثت چندسطحی شی گرایی در پایتون این امکان را فراهم می‌آورد تا کلاس فرزند، از کلاسی ارث‌بری کند که آن کلاس، خودش به عنوان کلاس فرزند محسوب می‌شود. به عبارتی، کلاس فرزند، علاوه بر کلاس والد خود، از کلاس والد والد خود نیز ارث‌بری می‌کند. در ادامه، ساختار نحوی پایتون برای تعریف وراثت چندسطحی ملاحظه می‌شود.

#Syntax_of_multilevel_inheritance

class A:
    pass

class B(A):
    pass

class C(B):
    pass

obj = C()

مثال زیر، نمونه‌ای از نحوه پیاده‌سازی اصل وراثت از نوع چندسطحی را در پایتون نشان می‌دهد. در این مثال، کلاس Produsts

به عنوان کلاس والد برای کلاس Popularity

تعریف شده است که خودش به عنوان کلاس فرزند برای کلاس Brands

محسوب می‌شود. بدین ترتیب، کلاس Popularity

از مشخصه‌های کلاس‌های Products

و Brands

ارث‌بری می‌کند.

class Brands:                      #parent_class
    brand_name_1 = "Amazon"
    brand_name_2 = "Ebay"
    brand_name_3 = "OLX"
    
class Products(Brands):            #child_class
    prod_1 = "Online Ecommerce Store"
    prod_2 = "Online Store"
    prod_3 = "Online Buy Sell Store"

class Popularity(Products):        #grand_child_class
    prod_1_popularity = 100
    prod_2_popularity = 70
    prod_3_popularity = 60
    
    
obj_1 = Popularity()          #Object_creation
print(obj_1.brand_name_1+" is an "+obj_1.prod_1+" popularity of "+str(obj_1.prod_1_popularity))
print(obj_1.brand_name_2+" is an "+obj_1.prod_2+" popularity of "+str(obj_1.prod_2_popularity))
print(obj_1.brand_name_3+" is an "+obj_1.prod_3+" popularity of "+str(obj_1.prod_3_popularity))

#Output
#Amazon is an Online Ecommerce Store popularity of 100
#Ebay is an Online Store popularity of 70
#OLX is an Online Buy Sell Store popularity of 60

وراثت سلسله مراتبی شی گرایی در پایتون چیست ؟

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

#syntax_of_hierarchical_inheritance

class A:                  #parent_class
    pass
    
class B(A):               #child_class
    pass

class C(A):               #child_class
    pass

class D(A):               #child_class
    pass

obj_1 = B()       #Object_creation
obj_2 = C()
obj_3 = D()

در مثال زیر، نمونه‌ای از وراثت سلسله مراتبی در پایتون ملاحظه می‌شود. در این مثال، کلاس‌های فرزند Popularity

، Value

و Products

از تنها کلاس والد Brands

ارث‌بری می‌کنند.

#example

class Brands:                      #parent_class
    brand_name_1 = "Amazon"
    brand_name_2 = "Ebay"
    brand_name_3 = "OLX"
    
class Products(Brands):            #child_class
    prod_1 = "Online Ecommerce Store"
    prod_2 = "Online Store"
    prod_3 = "Online Buy Sell Store"

class Popularity(Brands):        #grand_child_class
    prod_1_popularity = 100
    prod_2_popularity = 70
    prod_3_popularity = 60

class Value(Brands):
    prod_1_value = "Excellent Value"
    prod_2_value = "Better Value"
    prod_3_value = "Good Value"
    
obj_1 = Products()          #Object_creation
obj_2 = Popularity()
obj_3 = Value()
print(obj_1.brand_name_1+" is an "+obj_1.prod_1)
print(obj_1.brand_name_1+" is an "+obj_1.prod_1)
print(obj_1.brand_name_1+" is an "+obj_1.prod_1)

خروجی قطعه کد بالا در ادامه نشان داده شده است:

#Output
#Amazon is an Online Ecommerce Store
#Ebay is an Online Store
#OLX is an Online Buy Sell Store

وراثت ترکیبی در پایتون

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

آموزش برنامه نویسی پایتون + مثال های عملی در Python
فیلم آموزش برنامه نویسی پایتون + مثال های عملی در Python در تم آف

کلیک کنید

نمونه‌ای از ساختار نحوی پایتون را برای تعریف وراثت ترکیبی در ادامه ملاحظه می‌کنید.

#Syntax_Hybrid_inheritance

class PC: 
	pass
	
class Laptop(PC): 
	pass
	
class Mouse(Laptop): 
	pass
	
class Student3(Mouse, Laptop): 
	pass
	
# Driver's code 
obj = Student3()

در ادامه نیز، قطعه کدی از زبان پایتون ارائه شده است که مثالی از وراثت ترکیبی را نشان می‌دهد.

#Example_Hybrid_inheritance
class PC:
def fun1(self):
print(“This is PC class”)

class Laptop(PC):
def fun2(self):
print(“This is Laptop class inheriting PC class”)

class Mouse(Laptop):
def fun3(self):
print(“This is Mouse class inheriting Laptop class”)

class Student(Mouse, Laptop):
def fun4(self):
print(“This is Student class inheriting PC and Laptop”)

# Driver’s code
obj = Student()
obj1 = Mouse()
obj.fun4()
obj.fun3()

اصل کپسوله سازی شی گرایی در پایتون چیست ؟

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

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

به عبارتی، تمامی ویژگی‌ها و متدهای یک ماهیت، در یک کلاس تعریف می‌شوند و می‌توان مشخص کرد که با تعریف شی به کدام یک از این مشخصه‌ها می‌توان دسترسی داشت. بر اساس اصل کپسوله‌سازی شی گرایی، می‌توان سه نوع سطح دسترسی به مشخصه‌های درون کلاس اختصاص داد که در ادامه به آن‌ها اشاره شده است:

  • مشخصه‌هایی از نوع «عمومی» (Public)
  • مشخصه‌هایی از نوع «خصوصی» (Private)
  • مشخصه‌هایی از نوع «محافظت شده» (Protected)
کپسوله سازی در شی گرایی پایتون چیست

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

مشخصه های عمومی کلاس در پایتون

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

در قطعه کد زیر، مثالی از مشخصه‌های عمومی کلاس در زبان پایتون ارائه شده است. در این مثال، ویژگی‌های name

و age

و متد print_name

به عنوان مشخصه‌های عمومی کلاس Person

محسوب می‌شوند که با استفاده از شی object_person

می‌توان از خارج کلاس، به آن‌ها دسترسی داشت.

class Person: 
    def __init__(self, name, age): 
        self.name = name 
        self.age = age 
    def print_name(self):
        print('The name is :' , self.name)

object_person = Person('John', 25)
print(object_person.name)
object_person.print_name()

مشخصه های محافظت شده کلاس در پایتون

اصل کپسوله‌سازی شی گرایی این امکان را فراهم می‌کند تا بتوان مشخصه‌هایی در کلاس ایجاد کرد که از خارج کلاس، امکان دسترسی به آن‌ها وجود ندارد. تنها راه دسترسی به مشخصه‌های محافظت شده، از درون کلاس یا از داخل کلاس‌های فرزند است. این اصل باعث بالا بردن سطح امنیت در توسعه برنامه می‌شود.

آموزش کلاس در پایتون (رایگان)
فیلم آموزش کلاس در پایتون (رایگان) در تم آف

کلیک کنید

در زبان برنامه نویسی پایتون، بر خلاف سایر زبان‌های برنامه نویسی، منع دسترسی به مشخصه‌های حفاظت شده از خارج کلاس وجود ندارد. به عبارتی،‌ تعریف مشخصه‌های حفاظت شده به عنوان قراردادی بین برنامه‌نویسان این زبان است که صرفاً از نوع مشخصه آگاه باشند. بدین ترتیب، چنانچه از این مشخصه‌ها در خارج از کلاس استفاده شود، خطای کامپایلر رخ نمی‌دهد. به منظور تعریف مشخصه‌های حفاظت شده در پایتون از علامت ( _

 ) استفاده می‌شود.

در قطعه کد زیر، مثالی از نحوه کاربرد ویژگی‌های محافظت شده در پایتون ارائه شده است. در این مثال، متغیر _q

از نوع متغیر محافظت شده است که نام آن با علامت ( _

) آغاز می‌شود.

class Base1:  
    def __init__(self):  
          self._q = "Javatpoint"  

obj_1 = Base1()  
print(obj_1._q)  

خروجی قطعه کد بالا، در ادامه آمده است.

Javatpoint

به منظور تعریف متدهای محافظت شده درون کلاس نیز می‌توان قبل از نام متد، از علامت _

در پایتون استفاده کرد. در قطعه کد زیر، مثالی از نحوه تعریف متد محافظت شده در زبان پایتون ارائه شده است. همان‌طور که در این مثال ملاحظه می‌شود، متد _warmup

از نوع متد محافظت شده به حساب می‌آید.

class Person:
    def __init__(self, name):
        self.name = name
    def _warmup(self):
        print("{} is warming up".format(self.name))
jack = Person ('Jack')
jack._warmup()

خروجی قطعه کد بالا در ادامه ملاحظه می‌شود.

Jack is warming up

مشخصه های خصوصی کلاس در پایتون

مشخصه‌های خصوصی در شی گرایی نیز دارای محدودیت‌های دسترسی هستند. به عبارتی، به این نوع مشخصه‌ها نمی‌توان از خارج کلاس دسترسی داشت. علاوه بر این، کلاس‌های فرزند نیز محدودیت دسترسی به مشخصه‌های خصوصی کلاس والد خود را دارند. بدین ترتیب، مشخصه‌های خصوصی تنها از درون کلاس قابل دسترس هستند.

آموزش برنامه نویسی پایتون Python – مقدماتی
فیلم آموزش برنامه نویسی پایتون Python – مقدماتی در تم آف

کلیک کنید

بر خلاف سایر انواع زبان‌های برنامه نویسی، پایتون، مانع دسترسی به مشخصه‌های حفاظت شده از خارج کلاس نمی‌شود. به عبارتی،‌ تعریف مشخصه‌های خصوصی درون کلاس، به عنوان قراردادی بین برنامه‌نویسان این زبان محسوب می‌شود که صرفاً از نوع مشخصه آگاه باشند.

بدین ترتیب، چنانچه با کلاس‌های فرزند یا از طریق شی ساخته شده از بیرون کلاس بخواهیم به مشخصه‌های خصوصی در پایتون دسترسی داشته باشیم، خطای کامپایلر رخ نخواهد داد. به منظور تعریف ویژگی‌ها و متدهای خصوصی در پایتون از علامت ( __

) در ابتدای نام مشخصه‌ها استفاده می‌شود. در ادامه، مثالی از نحوه کاربرد ویژگی خصوصی در زبان پایتون ارائه شده است:

class Base1: 
    def __init__(self): 
        self.__q = "Javatpoint" 

obj_1 = Base1() 
print(obj_1.__q)

خروجی قطعه کد بالا، در ادامه ملاحظه می‌شود.

Javatpoint

برای تعریف متدهای خصوصی درون کلاس در زبان پایتون نیز می‌توان قبل از نام متد، از علامت ( __

) استفاده کرد. در قطعه کد زیر، مثالی از نحوه تعریف متد خصوصی در این زبان برنامه نویسی ارائه شده است.

class Person: 
    def __init__(self, name): 
        self.name = name 
    def __warmup(self): 
        print("{} is warming up".format(self.name))
jack = Person ('Jack')
jack.__warmup()

خروجی قطعه کد بالا در ادامه ملاحظه می‌شود.

Jack is warming up

اصل انتزاع شی گرایی در پایتون

اصل انتزاع در شی گرایی این امکان را فراهم می‌آورد تا بتوانیم کلاس انتزاعی بسازیم. کلاس Abstract یا همان انتزاعی نمونه‌ اولیه‌ای از یک کلاس است که با تعریف کلاس‌های فرزند می‌توان از متدهای آن کلاس ارث‌بری کرد. به منظور استفاده از کلاس‌های انتزاعی، نمی‌توان به‌طور مستقیم از آن‌ها شی ساخت.

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

به عبارتی، باید کلاس‌های فرزندی را ایجاد کرد که از کلاس‌های انتزاعی ارث‌بری می‌کنند و سپس با تعریف اشیای جدید از کلاس‌های فرزند، بتوان به متدهای کلاس‌های انتزاعی دسترسی داشت. کلاس انتزاعی شامل «متدهای انتزاعی» (Abstract Method) می‌شود.

متدهای انتزاعی، متدهایی هستند که صرفاً اعلان شده‌اند اما بدنه آن‌ها تعریف نشده است. کلاس‌های انتزاعی زمانی کاربرد دارند که بخواهیم کلاس‌های مختلفی ایجاد کنیم که دارای متدهایی با نام‌های یکسان باشند،‌ اما با استفاده از روش «بازنویسی متد» (Method Overriding)، دستورات متفاوتی را برای این متدها در کلاس‌های فرزند تعریف کنیم.

انتزاع در پایتون

بر خلاف کلاس‌های عادی در پایتون، برای تعریف کلاس انتزاعی باید از کتابخانه  استفاده کرد. به عبارتی،‌ به‌طور مستقیم نمی‌توان کلاس انتزاعی را در زبان پایتون تعریف کرد و باید از کتابخانه‌ای با نام abc

استفاده شود. در این کتابخانه، ماژولی با نام ABC

وجود دارد که باید برای تعریف کلاس انتزاعی در پایتون فراخوانی شود. برای ساخت متد انتزاعی در پایتون نیز پیش از خط اعلان متد، از دستور abc.abstractmethod

استفاده می‌شود.

در قطعه کد زیر، مثالی از نحوه تعریف کلاس انتزاعی در زبان پایتون ارائه شده است. در این مثال، کلاس AbstractClassName

از نوع کلاس انتزاعی است که ماژول ABC

در خط اعلان این کلاس صدا زده می‌شود. متد abstract_method_name

نیز متد انتزاعی کلاس است که با استفاده از دکوراتور @abstractmethod

به عنوان متد انتزاعی در نظر گرفته می‌شود.

from abc import ABC, abstractmethod


class AbstractClassName(ABC):
    @abstractmethod
    def abstract_method_name(self):
        pass

خاطر نشان می‌شود از آنجایی که متدهای انتزاعی دارای بدنه نیستند و بدنه آن‌ها درون کلاس فرزند باید بازنویسی شوند، باید در قسمت بدنه متدهای انتزاعی در پایتون از دستور pass

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

مطلب پیشنهادی:

کلاس Abstract در پایتون — به زبان ساده

شروع مطالعه

 

در قطعه کد زیر، مثالی کاربردی از کلاس انتزاعی و نحوه ارث‌بری از آن ارائه شده است. در این مثال، کلاس Employee

، کلاس انتزاعی است که یک متد انتزاعی با نام get_salary

دارد. کلاس‌های FulltimeEmployee

و HuprlyEmployee

کلاس‌های فرزند هستند که با روش بازنویسی متد، بدنه متد get_salary

در این کلاس‌ها با دستورات متفاوت تکمیل شده است.

from abc import ABC, abstractmethod


class Employee(ABC):
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

    @abstractmethod
    def get_salary(self):
        pass

class FulltimeEmployee(Employee):
    def __init__(self, first_name, last_name, salary):
        super().__init__(first_name, last_name)
        self.salary = salary

    def get_salary(self):
        return self.salary


class HourlyEmployee(Employee):
    def __init__(self, first_name, last_name, worked_hours, rate):
        super().__init__(first_name, last_name)
        self.worked_hours = worked_hours
        self.rate = rate

    def get_salary(self):
        return self.worked_hours * self.rate

اصل چندریختی در پایتون

اصل «چندریختی | پلی مورفیسم» (Polymorphism) یکی دیگر از اصول مهم شی‌گرایی است و به وضعیتی اطلاق می‌شود که ماهیتی نظیر متد، «عملگر» (Operator) یا شی در شرایط مختلف، رفتار متفاوتی داشته باشند.

آموزش برنامه نویسی پایتون Python – مقدماتی
فیلم آموزش برنامه نویسی پایتون Python – مقدماتی در تم آف

کلیک کنید

اصل چندریختی در شی گرایی با دو مفهوم «بازنویسی متد» (Method Overriding) و «سربارگذاری متد» (Method Overloading) سر و کار دارد. در بخش مربوط به اصل انتزاع به توضیح مفهوم بازنویسی متد پرداخته شد. از این روش در مواقعی استفاده می‌شود که در کلاس فرزند، متدی هم‌نام با متد کلاس والد ایجاد شود، به طوری که این متد شامل دستوراتی مغایر با دستورات متد کلاس والد باشد. به عبارتی، می‌توان گفت با اصل چندریختی، یک متد در کلاس‌های مختلف (در کلاس‌های فرزند) عملکرد متفاوتی دارد.

اصل چند ریختی در پایتون

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

class Example:
    def multiply(self,a,b,c=1):
        print(a*b*c)

example = Example()
example.multiply(5,10)
example.multiply(2,5,6)

در مثال بالا ملاحظه می‌شود که کلاس Example

دارای متدی با نام multiply

است که در ورودی سه پارامتر را دریافت می‌کند. اشیایی که مقداری برای پارامتر سوم نداشته باشند، به صورت پیش‌فرض، مقدار عددی ۱ برای آن‌ها لحاظ می‌شود. بدین ترتیب، بر اساس اصل چندریختی می‌توان متدی ایجاد کرد که تعداد مقادیر ارسالی به آن‌ها از طریق اشیای کلاس، متفاوت باشد.

مطلب پیشنهادی:

پلی مورفیسم در برنامه نویسی چیست ؟ — مفهوم به زبان ساده + مثال

شروع مطالعه

 

مدیریت ویژگی در کلاس های پایتون

گاهی لازم است برای دسترسی به ویژگی‌هایی که در کلاس وجود دارند، محدودیت‌هایی را لحاظ کنیم. به عنوان مثال، چنانچه کلاسی برای ماهیت Person تعریف کرده باشیم که دارای ویژگی‌های مختلفی نظیر اسم و سن باشد، می‌توان برای ویژگی سن، محدودیتی لحاظ کرد تا کاربر، این ویژگی را با مقادیر منفی مقداردهی نکند.

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

برای اعمال محدودیت بر روی ویژگی‌های کلاس، می‌توان از دو متد getter و setter در داخل کلاس استفاده کرد. به منظور درک بهتر مطلب حاضر، بهتر است مثالی در این باره ارائه کنیم. قطعه کد زیر را در نظر بگیرید که کلاسی را با نام Person

با ویژگی‌های name

و age

تعریف می‌کند.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age


john = Person('John', 18)

از آنجایی که age

به عنوان ویژگی نمونه تعریف شده است، می‌توان در ادامه برنامه، مقادیر آن را تغییر داد:

john.age = 19
...
...
...
john.age = -1

با این حال، تخصیص مقادیر منفی به ویژگی age

به لحاظ معنایی صحیح نیست. راه‌حل ساده‌ای که برای چنین مشکلی وجود دارد، این است که در قسمت‌هایی از برنامه که مقدار ویژگی age

تغییر می‌کند، شرطی را برای بررسی بازه مقدار عددی آن به صورت زیر در نظر بگیریم:

age = -1
if age 

با این حال، این روش باعث افزایش تعداد کدهای تکراری برنامه می‌شود و چنین راه‌حلی بهینه نیست. به جای استفاده از این روش، می‌توان از دو متد getter و setter در داخل کلاس استفاده کرد تا بر روی اعمال تغییرات در مقادیر ویژگی‌ها نظارتی انجام شود. به عبارتی، متدهای getter و setter به عنوان رابطی برای دسترسی به ویژگی‌های نمونه کلاس در پایتون محسوب می‌شوند. وظیفه این دو متد به شرح زیر است:

  • متد getter مقدار ویژگی‌ نمونه را در خروجی بازمی‌گرداند.
  • متد setter مقدار جدیدی را برای ویژگی نمونه لحاظ می‌کند.

در قطعه کد زیر، مثالی از نحوه تعریف متدهای getter و setter برای ویژگی age

ارائه شده است. خاطر نشان می‌شود به منظور استفاده از متدهای getter و setter بر اساس قرارداد، نوع ویژگی age

را که از نوع عمومی است،‌ به نوع محافظت شده (یعنی _age

) تبدیل می‌کنیم.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.set_age(age)

    def set_age(self, age):
        if age 

بر اساس قطعه کد ارائه شده، متد set_age()

به عنوان متد setter و متد get_age()

به عنوان متد getter محسوب می‌شوند. در متد set_age()

مقدار ویژگی age

بررسی می‌شود که اگر مقدار آن کم‌تر از عدد صفر باشد، خطایی به کاربر در خروجی نشان بدهد مبنی بر این که مقدار عددی ورودی برای ویژگی سن باید عددی مثبت باشد. متد get_age()

نیز مقدار ویژگی age

را در خروجی بازمی‌گرداند. در متد __init__()

نیز متد set_age()

را برای مقداردهی ویژگی age

فراخوانی می‌کنیم. بدین ترتیب، چنانچه مقداری منفی را برای ویژگی لحاظ کنیم، با اجرای برنامه با خطای زیر در خروجی مواجه می‌شویم:

ValueError: The age must be positive

 

تغییراتی که در کلاس Person

تا به اینجا اعمال کردیم، به درستی کار می‌کنند. با این حال، چنانچه از قبل، در حال توسعه پروژه نرم‌افزاری بوده باشید و قطعه کدهای خود را بر اساس کلاس به گونه‌ای نوشته باشید که تغییرات جدید مربوط به متدهای setter و getter را پشتیبانی نکنند، باید تمامی قسمت‌های برنامه خود را تغییر بدهید تا با نسخه جدید کلاس Person

مطابقت پیدا کنند.

البته شی گرایی در پایتون راه‌حل بهتری را برای رفع مشکل مطرح شده ارائه می‌دهد. چنانچه بخواهید متدهای getter و setter را در کلاس تعریف کنید، بهتر است که از تابع Property

 استفاده کنید. این کلاس، دارای چندین آرگومان ورودی است که در ادامه به آن‌ها اشاره شده است:

  • آرگومان fget

    : نام متد getter را مشخص می‌کند.

  • fset

    : نام متد setter را مشخص می‌کند.

  • آرگومان fdel

    : نام متدی است که مشخصه مورد نظر را حذف می‌کند.

در قطعه کد زیر، نحوه استفاده از تابع Property

ارائه شده است. بر اساس مثال زیر، در کلاس Person

شی جدیدی با نام age

از تابع Property

ایجاد شده است. شی age

به عنوان مشخصه کلاس Person

محسوب می‌شود.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def set_age(self, age):
        if age 

چنانچه مقدار ویژگی age

را با استفاده از شی john

از خارج کلاس تغییر دهید، پایتون متد set_age()

را از طریق آرگومان fset

فراخوانی می‌کند و مقدار ویژگی age

را تغییر می‌دهد. به منظور نمایش مقدار ویژگی age

در خروجی با استفاده از شیٔ در خارج از کلاس، می‌توان از دستور زیر استفاده کرد:

print(john.age)

علاوه بر روش بالا، می‌توان مستقیماً متد get_age()

را با استفاده از شی به صورت زیر فراخوانی کرد:

print(john.get_age())

تمرین برنامه نویسی شی گرا با زبان پایتون

در این بخش، چندین سوال و تمرین برنامه نویسی مرتبط با شی گرایی در پایتون ارائه می‌کنیم تا خوانندگان این مطلب، دانش خود را که از مطالعه محتوای آموزشی بخش‌های پیشین مطلب حاضر کسب کرده‌اند، مورد سنجش قرار دهند.

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

در ابتدا، سوالات برنامه نویسی مطرح می‌شوند و سپس خوانندگان مطلب، می‌توانند پاسخ خود را با راه‌حل ارائه شده مقایسه و از پاسخ خود اطمینان حاصل کنند. پیشنهاد می‌شود حتماً پیش از مشاهده پاسخ صحیح، مخاطبان خودشان نسبت به حل تمرین‌ها حداکثر تلاش خود را به کار گیرند و در نهایت پاسخ هود را با پاسخ صحیح مقایسه کنند. به این طریق یادگیری بسیار بهتر اتفاق خواهد افتاد.

تمرین ۱. تعریف کلاس در پایتون

با استفاده از پایتون، کلاسی با نام Vehicle

ایجاد کنید که هیچ گونه مشخصه‌ای نداشته باشد.

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

پاسخ تمرین ۱

پاسخ این تمرین به صورت زیر است:

class Vehicle:
    pass

تمرین ۲. تعریف مشخصه های کلاس و شی در پایتون

با استفاده از زبان برنامه نویسی پایتون، کلاسی با نام Vehicle

را ایجاد کنید که دارای دو متغیر نمونه با نام‌های max_speed

و mileage

باشد. سپس شیئ از این کلاس ایجاد کنید که با استفاده از آن، دو متغیر نمونه، با مقادیر دلخواه مقداردهی شوند. در نهایت، مقادیر متغیرهای نمونه را با استفاده از شی تعریف شده، در خروجی چاپ کنید.

پاسخ تمرین ۲

جواب تمرین ۲ در ادامه آمده است.

class Vehicle:
    def __init__(self, max_speed, mileage):
        self.max_speed = max_speed
        self.mileage = mileage

modelX = Vehicle(240, 18)
print(modelX.max_speed, modelX.mileage)

تمرین ۳. ارث بری در پایتون

با زبان پایتون قطعه کدی بنویسید که کلاس فرزندی را با نام Bus

ایجاد کند که تمامی مشخصه‌های خود را از کلاس والد Vehicle

به ارث می‌برد. مشخصه‌های کلاس والد می‌توانند شامل متغیرهای نمونه name

، max_speed

و mileage

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

پاسخ تمرین ۳

پاسخ این تمرین در ادامه مشاهده می‌شود.

class Vehicle:

    def __init__(self, name, max_speed, mileage):
        self.name = name
        self.max_speed = max_speed
        self.mileage = mileage

class Bus(Vehicle):
    pass

School_bus = Bus("School Volvo", 180, 12)
print("Vehicle Name:", School_bus.name, "Speed:", School_bus.max_speed, "Mileage:", School_bus.mileage)

تمرین ۴. باز نویسی متد در کلاس پایتون

با زبان پایتون برنامه‌ای بنویسید که کلاس فرزندی را با نام Bus

ایجاد کند که تمامی مشخصه‌های خود را از کلاس والد Vehicle

به ارث می‌برد.

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

مشخصه‌های کلاس والد می‌توانند شامل متغیرهای نمونه name

، max_speed

و mileage

باشند. همچنین، در کلاس والد، متدی با نام seating_capacity

را تعریف کنید که پارامتری با نام seating_capacity

دریافت کند. متد seating_capacity

را در کلاس فرزند با استفاده از بازنویسی متد به نحوی تغییر دهید که مقدار پیش‌فرض ۵۰ برای پارامتر این تابع در نظر گرفته شود.

پاسخ تمرین ۴

پاسخ تمرین ۴ به صورت زیر است.

class Vehicle:
    def __init__(self, name, max_speed, mileage):
        self.name = name
        self.max_speed = max_speed
        self.mileage = mileage

    def seating_capacity(self, capacity):
        return f"The seating capacity of a {self.name} is {capacity} passengers"

class Bus(Vehicle):
    # assign default value to capacity
    def seating_capacity(self, capacity=50):
        return super().seating_capacity(capacity=50)

School_bus = Bus("School Volvo", 180, 12)
print(School_bus.seating_capacity())

تمرین ۵. متغیرهای کلاس در پایتون

با استفاده از زبان برنامه نویسی پایتون قطعه کدی برای ساخت کلاس والد با نام Vehicle

بنویسید که علاوه بر متغیرهای نمونه name

، max_speed

و mileage

، متغیر کلاسی با نام Color

نیز داشته باشد تا مقدار این متغیر برای تمامی اشیای ساخته شده از کلاس والد و تمامی کلاس‌های فرزند آن به اشتراک گذاشته شود.

آموزش برنامه نویسی شی گرا در پایتون Python
فیلم آموزش برنامه نویسی شی گرا در پایتون Python در تم آف

کلیک کنید

کلاس‌های فرزندی با نام‌های Bus

و Car

نیز ایجاد کنید که از کلاس Vehicle

ارث‌بری می‌کنند. برای هر یک از این کلاس‌های فرزند، شیئی بسازید و مقادیری برای متغیرهای نمونه آن‌ها تعریف کنید. در نهایت، مقادیر تمامی مشخصه‌های اشیاء را در خروجی نشان دهید.

پاسخ تمرین ۵

پاسخ این تمرین در ادامه آمده است.

class Vehicle:
    # Class attribute
    color = "White"

    def __init__(self, name, max_speed, mileage):
        self.name = name
        self.max_speed = max_speed
        self.mileage = mileage

class Bus(Vehicle):
    pass

class Car(Vehicle):
    pass

School_bus = Bus("School Volvo", 180, 12)
print(School_bus.color, School_bus.name, "Speed:", School_bus.max_speed, "Mileage:", School_bus.mileage)

car = Car("Audi Q5", 240, 18)
print(car.color, car.name, "Speed:", car.max_speed, "Mileage:", car.mileage)

تمرین ۶. بررسی رابطه والد و فرزندی بین کلاس ها

کلاس والدی با نام Vehicle

و کلاس فرزندی با نام Bus

ایجاد کنید و درنهایت مشخص کنید آیا کلاس Bus

به عنوان کلاس فرزند برای کلاس Vehicle

محسوب می‌شود یا خیر؟

پاسخ تمرین ۶

جواب تمرین ۶ در ادامه ارائه شده است.

class Vehicle:
    def __init__(self, name, mileage, capacity):
        self.name = name
        self.mileage = mileage
        self.capacity = capacity

class Bus(Vehicle):
    pass

School_bus = Bus("School Volvo", 12, 50)

# Python's built-in isinstance() function
print(isinstance(School_bus, Vehicle))

جمع‌بندی

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

به علاوه، شی گرایی دارای چهار اصل مهم است که توسعه برنامه‌های مبتنی بر این رویکرد باید بر پایه این چهار اصل انجام شوند. در این مطلب، به چهار اصل مهم شی گرایی پرداخته و مفاهیم آن‌ها با استفاده از مثال‌های کاربردی در زبان پایتون ارائه شد.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.