کلاس در پایتون چیست؟ — آموزش کامل ساخت و استفاده + کد و مثال
«کلاس» (Class) یکی از مهمترین و پرکاربردترین مفاهیم در برنامه نویسی محسوب میشود. کلاس بستری را فراهم میکند تا دادهها و توابع در کنار یکدیگر قرار بگیرند که همین امر در بهتر شدن کدنویسی بهصورت سازمانیافته نقش بهسزایی دارد. کلاس در پایتون به عنوان یکی از اساسیترین مفاهیم این زبان تلقی میشود، زیرا تمامی ماهیتهای این زبان برنامه نویسی بر پایه مفهوم کلاس بنا شدهاند. همچنین، زبان پایتون جزء زبانهای برنامه نویسی شیگرا به شمار میرود که از کلاس، به عنوان مهمترین عنصر شی گرایی، به منظور پیادهسازی اصول آن استفاده میکند.
در مطلب حاضر، سعی بر این است تا آموزش جامعی از مفهوم کلاس و اجزای اصلی آن، نحوه پیادهسازی و استفاده از آن در زبان پایتون ارائه شود. بهعلاوه، در این مقاله، با ارائه مثالهای کاربردی از زبان برنامه نویسی پایتون به نحوه پیادهسازی اصول شیگرایی با استفاده از کلاس پرداخته میشود.
مفهوم شی در زبان برنامه نویسی پایتون چیست ؟
زبان برنامه نویسی پایتون به عنوان یکی از زبانهای برنامه نویسی شی گرا محسوب میشود. یکی از اجزای اصلی مفهوم شیگرایی، «شی» (Object) است که ویژگیها و رفتارهای دادهها را مشخص میکند. تمامی اجزای زبان پایتون نظیر «لیست» (List)، «تاپل» (Tuple)، «مجموعه» (Set)، «دیکشنری» (Dictionary)، «تابع» (Function) و سایر اجزاء در قالب شی در اختیار کاربران قرار میگیرند. به عبارتی، با استفاده از دستور Type در پایتون میتوان شی بودن این اجزاء را در پایتون بررسی کرد.
حتی «انواع داده» (Data Types) در پایتون نیز از نوع و ماهیت شی هستند. به عنوان مثال، یکی از انواع دادهها در زبان برنامه نویسی پایتون، نوع داده عددی (Integer) است. متغیری که در این زبان از نوع عددی تعریف شده باشد، عضو یا شیئی از کلاس Integer محسوب میشود.
هر یک از اشیای ساخته شده در پایتون دارای یک سری «ویژگیها» (Properties) و «رفتارهایی | متدهایی» (Methods) هستند که در دنیای برنامه نویسی به آنها «مشخصه» (Attribute) گفته میشوند. به منظور تعریف هر یک از ویژگیها و متدهای اشیا میتوان از ماهیت منطقی به نام کلاس استفاده کرد. در ادامه، به مفهوم کلاس در زبان برنامه نویسی پایتون پرداخته میشود.
مفهوم کلاس در زبان پایتون چیست ؟
کلاس در برنامه نویسی، طرح اولیهای از یک شی است و با تعریف اشیای مختلف از یک کلاس میتوان موجودیتهای (اشیای) مختلفی را ایجاد کرد که در تعداد و نوع مشخصهها با یکدیگر اشتراک دارند، اما مقادیر هر یک از مشخصههای اشیاء با یکدیگر متفاوت هستند.
با استفاده از تعریف اشیای مختلف به عنوان «نمونهای» (Instance) از کلاس، میتوان به ویژگیها و متدهای درون کلاس دسترسی داشت و آنها را برای هر شی جدید، مقداردهی کرد.
در تصویر زیر، مثال ملموسی از مفهوم کلاس و شی در دنیای واقعی مشاهده میشود. در این مثال، کلاسی با نام کلاس مشتری وجود دارد که شامل ویژگیهای مشتریان و عملکرد (متد) آنها است. ایمیل و شماره تلفن مشتریان به عنوان ویژگیها و نحوه سفارش و دلیل مرجوعی کالا به عنوان متدهای کلاس تعیین شدهاند.
هر یک از مشتریان نیز به عنوان اشیای کلاس مشتری تلقی میشوند که دارای ویژگیها و متدهای کلاس با مقادیر متفاوت هستند. به عبارتی، تمامی مشتریان دارای ویژگیهای آدرس ایمیل و شماره تلفن هستند که مقدارشان برای هر یک از مشتریان، منحصربفرد است. بهعلاوه، تمامی مشتریان دارای متدهای نحوه سفارش کالا و دلیل مرجوعی محصول هستند که میتوانند با مقادیر مختلفی مقداردهی شوند. به عنوان مثال، دلیل مرجوعی مشتری اول میتواند خرابی محصول باشد، در حالی که مشتری سوم به دلیل گذشتن تاریخ انقضای محصول، تصمیم به مرجوع کردن کالا گرفته است.
زبان برنامه نویسی پایتون به عنوان یکی از زبانهای برنامه نویسی شیگرا، بر پایه مفهوم شی و کلاس طراحی شده است. به عبارتی، با تعریف هر ماهیتی در این زبان نظیر انواع ساختار داده، شی جدیدی از کلاسهای آنها ساخته میشوند که هر کدام دارای مشخصههای خاص خود هستند. به عنوان مثال، با تعریف لیست جدیدی در پایتون، شی جدیدی از کلاس لیست ساخته میشود که این شی دارای مشخصههای منحصربفردی برای عملیات مختلف نظیر درج آیتم در لیست، حذف آیتم از لیست، اندازه لیست و سایر موارد است. بدینتریب، کلاس در پایتون به عنوان یکی از مهمترین ارکان این زبان محسوب میشود. در ادامه، مزایای استفاده از کلاس در برنامه نویسی پایتون ارائه شده است.
مزایای استفاده از کلاس در برنامه نویسی پایتون چیست ؟
کلاس یکی از مهمترین مفاهیم در برنامه نویسی محسوب میشود که کاربرد زیادی در توسعه پروژههای نرمافزاری دارد. به دلیل مزیتهای مهم کلاس، برنامهنویسان سعی دارند از آن بهطور مکرر در برنامههای خود استفاده کنند. در ادامه، به برخی از اصلیترین مزایای استفاده از کلاس در برنامه نویسی اشاره میشود:
- در زبان پایتون، نگهداری مشخصهها و متدهای اشیا در داخل کلاس باعث میشود سازماندهی کدها بهتر انجام شود.
- کلاس به عنوان یکی از اجزای اصلی شیگرایی محسوب میشود و با استفاده از آن میتوان به پیادهسازی اصول شیگرایی نظیر کپسولهسازی و ارثبری پرداخت. از آنجا که پایتون به عنوان یکی از زبانهای برنامه نویسی شیگرا به حساب میآید، از کلاس به منظور اجرایی کرد اصول شیگرایی پشتیبانی میکند.
- با استفاده از کلاس در پایتون میتوان از قطعه کدهای نوشته شده به دفعات مختلف در پروژههای متفاوت استفاده کرد که همین امر به صرفهجویی در هزینههای زمانی برای توسعه پروژههای کامپیوتری کمک شایانی میکند.
- با استفاده از کلاس در پایتون میتوان توابع مرتبط به هم را درون یک کلاس نوشت که این قابلیت در تمیز نوشتن کدهای برنامه نقش بسزایی دارد.
در ادامه مقاله حاضر، با ارائه مثال کاربردی به نحوه تعریف کلاس در پایتون و شیوه استفاده از آن پرداخته میشود.
نحوه ساخت کلاس در زبان پایتون چگونه است ؟
به منظور تعریف کلاس در پایتون باید از کلمه کلیدیclass به همراه نام کلاس و علامت دو نقطه (:) استفاده کرد. در پایتون، حرف اول نام کلاس، با حرف بزرگ نوشته میشود و باید از درج فاصله در نام کلاس خودداری کرد.
پس از اعلان کلاس، میتوان از «داک استرینگ» (Docstring) استفاده کرد. داک استرینگها توضیحاتی در پایتون هستند که پس از اعلان کلاس یا تابع نوشته میشوند و شرحی از عملیات آنها را ارائه میدهند. نوشتن داک استرینگها الزامی نیستند اما به خوانایی کد و قابلفهم کردن آن کمک بهسزایی میکند. مثال زیر، نحوه تعریف یک کلاس با نامIntellipaatClass را نشان میدهد.
1class IntellipaatClass:
2 “Class statements and methods here'”
پس از داک استرینگها میتوان ویژگیهای کلاس را با استفاده از تعریف متغیر مشخص کرد. در مثال زیر، متغیرa یک ویژگی برای کلاسIntellipaatClassمحسوب میشود. پس از تعریف متغیرهای کلاس، میتوان متدهای (توابع) کلاس را تعریف کرد. کلاسIntellipaatClassدارای یک متد با نامfunction1 است که متنی را در خروجی چاپ میکند.
با اعلان کلاس جدید، بهطور خودکار، شیئی همنام با کلاس ایجاد میشود که میتوان با استفاده از آن، به ویژگیها و متدهای کلاس دسترسی داشت. در مثال زیر، نحوه استفاده از شی همنام با کلاس به منظور دسترسی به متغیر (ویژگی) و تابع (متد) درون کلاس ملاحظه میشود. علامت نقطه (. ) به منظور دسترسی به مشخصههای کلاس توسط شی کاربرد دارد.
1#3
2class IntellipaatClass:
3 a = 5
4 def function1():
5 print('Welcome to Intellipaat')
6#accessing attributes using the class object of same name
7IntellipaatClass.function1()
8print(IntellipaatClass.a)
خروجی قطعه کد فوق در ادامه ملاحظه میشود:
Welcome to Intellipaat 5
نحوه تعریف کلاس در زبان پایتون با استفاده از تابع Type()
تابعtype()علاوهبر این که نوع ماهیتها را در زبان پایتون مشخص میکند، کاربرد دیگری نیز دارد. از این تابع میتوان برای ایجاد کلاس در پایتون نیز استفاده کرد. این تابع سه آرگومان به عنوان ورودی خود بهصورتtype(<name>, <bases>, <dct>) میپذیرد که در ادامه به توضیح آنها پرداخته شده است:
- آرگومانname : نام کلاس جدید را مشخص میکند. این نام توسط ویژگی__name__کلاس، قابل دسترس است.
- آرگومانbases : تاپلی از کلاسهای والد کلاس جدید را مشخص میکند.
- آرگومانdct : دیکشنریای از متدها و ویژگیهای کلاس جدید را معین میکند.
در قطعه کد زیر، مثالی از نحوه کاربرد تابعtype()برای ساخت کلاس در پایتون ارائه شده است.
1def test_method(self):
2 print("This is Test class method!")
3
4# creating a base class
5class Base:
6 def myfun(self):
7 print("This is inherited method!")
8
9# Creating Test class dynamically using
10# type() method directly
11Test = type('Test', (Base, ), dict(x="atul", my_method=test_method))
12
13# Print type of Test
14print("Type of Test class: ", type(Test))
15
16# Creating instance of Test class
17test_obj = Test()
18print("Type of test_obj: ", type(test_obj))
19
20# calling inherited method
21test_obj.myfun()
22
23# calling Test class method
24test_obj.my_method()
25
26# printing variable
27print(test_obj.x)
همانطور که در قطعه کد فوق ملاحظه میشود، کلاسی با نامTestبا استفاده از تابعtypeساخته شده است که از کلاسBaseارث میبرد و دارای یک ویژگی با نامxو یک متد با عنوانmy_methodاست. خروجی قطعه کد فوق در ادامه آمده است:
Type of Test class: <class 'type'> Type of test_obj: <class '__main__.Test'> This is inherited method! This is Test class method! atul
نحوه استفاده از کلاس در زبان پایتون چگونه است ؟
در بخش قبل ملاحظه شد که با ایجاد کلاس در پایتون، بهطور خودکار شی همنامی با کلاس ساخته میشود و از آن میتوان به منظور دسترسی به متغیرها و توابع درون کلاس استفاده کرد.
«ایجاد نمونه» (نمونهسازی | Instantiation) یا همان تعریف شی جدید، روش دیگری است که از آن برای دسترسی به ویژگیها و متدهای درون کلاس استفاده میشود. در این روش، میتوان اشیای جدیدی با نامهای مختلف از یک کلاس ایجاد کرد و با استفاده از این اشیای جدید، به اجزای درون کلاس دسترسی داشت. به عبارتی، شی ساخته شده، رونوشتی از کلاس است که مقادیر مشخصههای آن با مقادیر مشخصههای سایر اشیای همین کلاس، فرق دارد. در قطعه کد زیر، نحوه ساخت یک شی به نام object1 ملاحظه میشود.
1class IntellipaatClass:
2 a = 5
3 def function1(self):
4 print(‘Welcome to Intellipaat’)#creating a new object named object1 using class object
5
6object1 = IntellipaatClass()
7object1.function1()
خروجی قطعه کد فوق بهصورت زیر است:
Welcome to Intellipaat
انواع ویژگی های کلاس در زبان برنامه نویسی پایتون چیست ؟
همانطور که پیش از این توضیح داده شد، «ویژگیهای کلاس» (Class Properties) متغیرهایی هستند که اطلاعات مربوط به شی را ذخیره میکنند. ویژگیهای پایتون را میتوان به دو دسته کلی بهصورت فهرست زیر تقسیمبندی کرد:
- ویژگیهایی که توسط برنامه نویس تعریف میشوند:
- «متغیرهای کلاس» (Class Variables)
- «متغیرهای نمونه» (Instance Variables)
- ویژگیهای توکار پایتون
در ادامه مطلب حاضر، به شرح هر یک از اجزاء و قابلیتهای کلاس در پایتون به همراه مثال پرداخته میشود.
متغیرهای نمونه و متغیرهای کلاس
در کلاس پایتون میتوان دو نوع متغیر برای ذخیرهسازی دادهها تعریف کرد. این دو نوع متغیر در ادامه فهرست شدهاند:
- «متغیرهای کلاس» (Class Variables): متغیرهایی هستند که پس از اعلان کلاس تعریف میشوند. این متغیرها خارج از توابع (متدها) و در داخل کلاس قرار گرفتهاند. مقدار این نوع متغیرها برای تمامی اشیای ساخته شده از یک کلاس واحد، یکسان است. مقادیر متغیرها را صرفاً میتوان با استفاده از «متدهای کلاس» (Class Methods) تغییر داد. در بخش «انواع متدهای کلاس در پایتون» در مطلب حاضر، به توضیح متدهای کلاس پرداخته شده است.
- «متغیرهای نمونه» (Instance Variables): متغیرهایی هستند که درون توابع (متدها) و «سازندهها» (Constructors) تعریف میشوند. مقادیر این متغیرها برای هر یک از اشیای ساخته شده از یک کلاس مشابه، میتوانند متفاوت باشند. به عبارتی، متغیرهای نمونه، همان ویژگیهای کلاس محسوب میشوند و توسط نام شی یا پارامترselfمیتوان به آنها دسترسی داشت. در بخش «انواع متدهای کلاس در پایتون» در مطلب حاضر، به توضیح پارامترselfپرداخته شده است.
در قطعه کد زیر، مثالی از متغیرهای کلاس و متغیرهای نمونه ملاحظه میشود.
1class TrafficLight:
2 '''This is an updated traffic light class'''
3
4 # Class variable
5 traffic_light_address = 'NYC_Cranberry_Hicks'
6
7 def __init__(self, color):
8
9 # Instance variable assigned inside the class constructor
10 self.color = color
11
12 def action(self):
13 if self.color=='red':
14
15 # Instance variable assigned inside a class method
16 self.next_color = 'yellow'
17 print('Stop & wait')
18 elif self.color=='yellow':
19 self.next_color = 'green'
20 print('Prepare to stop')
21 elif self.color=='green':
22 self.next_color = 'red'
23 print('Go')
24 else:
25 self.next_color = 'Brandy'
26 print('Stop drinking ')
27
28# Creating class objects
29for c in ['red', 'yellow', 'green', 'fuchsia']:
30 c = TrafficLight(c)
31 print(c.traffic_light_address)
32 print(c.color)
33 c.action()
34 print(c.next_color)
35 print('n')
در مثال فوق، متغیرtraffic_light_address از نوع متغیر کلاس است و مقدار آن برای تمامی اشیای ساخته شده از کلاسTrafficLight یکسان است. متغیرcolor که در تابع سازنده__init__و متغیرnext_colorکه در متدactionتعریف شدهاند، نمونهای از متغیرهای نمونه هستند که مقادیرشان میتوانند به ازای هر شی جدید، متفاوت باشند. خروجی قطعه کد فوق به ازای اشیایred،yellow،greenوfuchsiaدر ادامه ملاحظه میشود.
NYC_Cranberry_Hicks red Stop & wait yellow NYC_Cranberry_Hicks yellow Prepare to stop green NYC_Cranberry_Hicks green Go red NYC_Cranberry_Hicks fuchsia Stop drinking Brandy
ویژگی های توکار کلاس در زبان پایتون چیست ؟
کلاسهای زبان پایتون علاوهبر ویژگیهایی که توسط برنامه نویس ساخته میشوند، دارای ویژگیهای توکار (پیشساخته | آماده) نیز هستند که اطلاعاتی را درباره کلاس در بر میگیرند. به ویژگیهای توکار کلاس نیز میتوان با استفاده از علامت نقطه (.) دسترسی داشت که پس از نام شی درج میشود. در ادامه، فهرستی از ویژگیهای توکار در کلاس پایتون ارائه شده است.
- ویژگی__dict__
- ویژگی__doc__
- ویژگی__name__
- ویژگی__module__
- ویژگی__bases__
در بخشهای بعدی مطلب حاضر، به توضیح کاربرد هر یک از ویژگیهای توکار ذکر شدهی بالا به همراه مثال پرداخته میشود.
ویژگی __dict__ شی در پایتون
از ویژگی__dict__به منظور نمایش تمامی ویژگیهای کلاس به همراه مقادیر آنها در قالب دیکشنری پایتون استفاده میشود. هر شی در پایتون دارای ویژگی توکار__dict__است که با استفاده از علامت نقطه (.) میتوان به آن دسترسی داشت. در قطعه کد زیر، مثالی از نحوه استفاده از ویژگی__dict__ملاحظه میشود.
1class AnimalClass:
2 def __init__(self,identity,age):
3 self.identity = identity
4 self.age = age
5
6 def feature(self):
7 if self.age == "10":
8 return True
9 else:
10 return False
11ac = AnimalClass('Lion','10')
12print(ac.__dict__)
در مثال فوق، کلاسAnimalClassدارای دو ویژگیidentityوageاست که این دو ویژگی در هنگام ساخت شیacبا مقادیرLionو10مقداردهی شدهاند. با استفاده از دستورac.__dict__، کلیه ویژگیهای کلاس در قالب دیکشنری بهصورت زیر در خروجی نشان داده میشوند:
{'identity': 'Lion', 'age': '10'}
ویژگی __doc__ شی در پایتون
اشیای پایتون دارای ویژگی توکاری با نام__doc__ هستند که داک استرینگ کلاس را بازمیگرداند. چنانچه کلاسی دارای داک استرینگ نباشد، این ویژگی، مقدار None را در خروجی برمیگرداند. در قطعه کد زیر، مثالی از نحوه کاربرد ویژگی__doc__ در پایتون ملاحظه میشود.
1# class
2class Awesome:
3 'This is a sample class called Awesome.'
4
5 def __init__(self):
6 print("Hello from __init__ method.")
7
8# class built-in attribute
9print(Awesome.__doc__)
با اجرای قطعه کد فوق، خروجی بهصورت زیر است:
This is a sample class called Awesome.
ویژگی __name__ شی در پایتون
از ویژگی توکار__name__در پایتون به منظور نمایش نام کلاس استفاده میشود. قطعه کد زیر، شیوه استفاده از این ویژگی را در پایتون نشان میدهد.
1# class
2class Awesome:
3 'This is a sample class called Awesome.'
4
5 def __init__(self):
6 print("Hello from __init__ method.")
7
8# class built-in attribute
9print(Awesome.__name__)
خروجی قطعه کد فوق، در ادامه ملاحظه میشود:
Awesome
ویژگی __module__ شی در پایتون
کلاس پایتون دارای ویژگی توکاری با نام__module__است که نام ماژول کلاس را مشخص میکند. در قطعه کد زیر، مثالی از شیوه کاربرد ویژگی در پایتون ملاحظه میشود.
1# class
2class Awesome:
3 def __init__(self):
4 print("Hello from __init__ method.")
5
6# class built-in attribute
7print(Awesome.__module__)
خروجی قطعه کد فوق بهصورت زیر است:
__main__
ویژگی __bases__ شی در پایتون
اشیای پایتون دارای ویژگی توکار__bases__به منظور نمایش نام کلاس والد کلاس اشیا است. در قطعه کد زیر، مثالی از کاربرد این ویژگی ارائه شده است.
1class A(object):
2 pass
3class B(A):
4 pass
5b = B()
6print (b.__bases__)
در قطعه کد فوق ملاحظه میشود که دو کلاس با نامهایAوBساخته شدهاند که کلاسBاز کلاسAارثبری میکند. شیئی با نامbنیز از کلاسBایجاد شده است و ویژگی__bases__این شی، کلاس والد آن، یعنی کلاسAرا بهصورت زیر در خروجی نشان میدهد:
(<class '__main__.A'>,)
تغییر ویژگی های کلاس و حذف شی در پایتون
با استفاده از شی تعریف شده، میتوان از خارج کلاس، به ویژگیهای کلاس دسترسی داشت و مقدار متغیرهای درون کلاس را تغییر داد. در قطعه کد زیر، مثالی از نحوه تغییر مقدار متغیرaاز کلاسIntellipaatClassملاحظه میشود.
1object1.a = 25
همچنین، میتوان شی ساخته شده را با استفاده از دستورdelبهصورت زیر حذف کرد.
1del objectName
معرفی فیلم های آموزش پایتون
افرادی که علاقهمند هستند برنامه نویسی پایتون را یاد بگیرند، میتوانند از مجموعه فیلمهای جامع آموزشی پایتون سایت فرادرس استفاده کنند. سایت فرادرس پلتفرمی را برای آن دسته از افرادی فراهم کرده است که قصد یادگیری پایتون را بهصورت حرفهای دارند. دورههای گردآوری شده در مجموعه آموزش پایتون، شامل فیلمهای آموزشی این زبان برنامه نویسی از سطح مقدماتی تا سطح پیشرفته است و مثالهای کاربردی و پروژههای واقعی زبان پایتون را شامل میشوند. افراد میتوانند از دورههای جامع پایتون در راستای تقویت مهارت برنامه نویسی خود استفاده کنند و از آموزشهای پروژهمحور فرادرس بهره بگیرند. در تصویر فوق تنها برخی از دورههای آموزشی مجموعه آموزش پایتون فرادرس مشاهده میشوند.
- برای دسترسی به همه آموزش های پایتون فرادرس + اینجا کلیک کنید.
انواع متدهای کلاس در زبان پایتون چیست ؟
در زبان برنامه نویسی پایتون، کلاسها میتوانند شامل چهار نوع متد باشند که در ادامه فهرستی از آنها فراهم شده است:
- «متد نمونه» (Instance Method)
- «متد کلاس» (Class Method)
- «متد ایستا» (Static Method)
- «متد خاص» (Special Method)
در ادامه مطلب حاضر به توضیح هر یک از انواع متدهای کلاس در زبان برنامه نویسی پایتون پرداخته میشود.
متد نمونه در کلاس های پایتون
متد نمونه در کلاس پایتون مجموعهای از عملیات را بر روی متغیرهای نمونه کلاس اعمال میکند. بهطور پیشفرض، هر متدی که درون کلاس ایجاد میشود، بهطور خودکار پایتون آن را به عنوان متد نمونه در نظر میگیرد. در قطعه کد زیر، مثالی از نحوه ساخت متد نمونه در کلاس پایتون ملاحظه میشود. در این مثال، متدfunction1، متد نمونه برای کلاسIntellipaatClassبه حساب میآید که با استفاده از شیobject1میتوان به آن دسترسی داشت.
1class IntellipaatClass:
2 a = 5
3 def function1(self):
4 print('Welcome to Intellipaat')
5
6#creating a new object named object1 using class object
7object1 = IntellipaatClass()
8object1.function1()
متد نمونه صرفاً توسط شی کلاس مورد استفاده قرار میگیرد و اولین پارامتر این متد، پارامترselfاست که به شی ساخته شده از کلاس اشاره دارد.
پارامتر self در کلاس پایتون چیست ؟
در مثال قبل ملاحظه میشود که در هنگام تعریف متد نمونه داخل کلاس، از آرگومانی با نامself استفاده شده با اینکه هیچ مقداری توسط شیobject1 به تابعfunction1 منتقل نشده است.
باید خاطرنشان کرد در زبان برنامه نویسی پایتون، زمانی که یک تابع (متد) توسط شیئی صدا زده میشود، بهطور خودکار شی به عنوان پارامتر، به آن تابع ارسال میشود. به عبارتی، دستورobject1.function1() در زبان پایتون، معادل دستورobject1.function1(object1)است و پایتون بهطور خودکار تغییر زیر را بر روی توابع خوانده شده توسط اشیای کلاس اعمال میکند:
obj.method(arg1, arg2, ..., argN) ➡️ MyClass.method(obj, arg1, arg2, ..., argN)
به همین خاطر، اولین آرگومان تابع درون کلاس، باید آرگومانselfباشد که به شی کلاس اشاره دارد. میتوان نام self را تغییر داد و از نامهای دیگری بهجای self استفاده کرد. اما به منظور فهم دقیقتر کدها و پایبند بودن به قراردادهای زبان پایتون، بهتر است که از همان کلمه self برای اشاره به شی استفاده شود.
متد کلاس در زبان پایتون
با استفاده از متد کلاس (Class Method) میتوان مقادیر متغیرهای کلاس (Class Variables) را تغییر داد. همانطور که قبلا اشاره شد، مقادیر متغیرهای کلاس برای تمامی اشیای ساخته شده از کلاس، یکسان هستند و در داخل کلاس و بیرون از تمامی متدهای کلاس، تعریف میشوند.
به منظور تغییر مقادیر متغیرهای کلاس، میتوان از متد کلاس استفاده کرد که اعمال تغییر مقدار متغیرهای کلاس توسط این متد، بر روی تمامی اشیای ساخته شده از کلاس اثرگذار است.
به منظور تعریف متد کلاس در پایتون از دو روش «دکوراتور» (Decorator)@classmethodو تابعclassmethod()استفاده میشود که در ادامه، به توضیح هر دو روش ذکر شده به همراه مثال پرداخته میشود.
تعریف متد کلاس با استفاده از دکوراتور
به منظور ساخت متد کلاس در پایتون، میتوان پیش از اعلان متد از دکوراتور@classmethodاستفاده کرد و پارامترclsرا نیز به عنوان اولین پارامتر متد، در دستور اعلان متد در نظر گرفت. دکوراتور@classmethodیک تابع توکار در پایتون محسوب میشود. در مثال زیر، نحوه ساخت متد کلاس در پایتون با استفاده از دکوراتور@classmethodارائه شده است.
1from datetime import date
2
3class Student:
4 def __init__(self, name, age):
5 self.name = name
6 self.age = age
7
8 @classmethod
9 def calculate_age(cls, name, birth_year):
10 # calculate age an set it as a age
11 # return new object
12 return cls(name, date.today().year - birth_year)
13
14 def show(self):
15 print(self.name + "'s age is: " + str(self.age))
16
17jessa = Student('Jessa', 20)
18jessa.show()
19
20# create new object using the factory method
21joy = Student.calculate_age("Joy", 1995)
22joy.show()
در مثال فوق، متدcalculate_ageیک نوع متد کلاس محسوب میشود که پیش از آن از دکوراتور@classmethodاستفاده شده است. پارامترهای این متد شامل سه پارامترcls،nameوbirth_yearهستند که دو پارامترnameوbirth_yearاز خارج کلاس و با دستور Student.calculate_age("Joy", 1995) مقداردهی میشوند. خروجی قطعه کد فوق بهصورت زیر است.
Jessa's age is: 20 John's age is: 26
تعریف متد کلاس با استفاده از تابع Classmethod
روش دیگری که از آن میتوان به منظور ایجاد متد کلاس در پایتون استفاده کرد، تابع توکارclassmethod()است. ورودی این تابع، متدی است که در نهایت به متد کلاس تبدیل میشود. به عبارتی، خروجی تابعclassmethod()، متدی از نوع متد کلاس است. شیوه استفاده از این تابع در ادامه ملاحظه میشود.
1classmethod(function)
متدی که با استفاده از تابعclassmethod()به متد کلاس تبدیل میشود، باید دارای پارامترclsباشد. در قطعه کد زیر، مثالی از نحوه کاربرد تابعclassmethod()برای تعریف متد کلاس ملاحظه میشود.
1class School:
2 # class variable
3 name = 'ABC School'
4
5 def school_name(cls):
6 print('School Name is :', cls.name)
7
8# create class method
9School.school_name = classmethod(School.school_name)
10
11# call class method
12School.school_name()
در قطعه کد فوق، کلاسی با نامSchoolایجاد شده است که متدی به نامschool_nameدارد. این متد با استفاده از دستور classmethod(School.school_name) ، به متد کلاس تبدیل میشود و میتوان با نام کلاس به آن دسترسی داشت. خروجی قطعه کد بالا در ادامه ملاحظه میشود:
School Name is : ABC School
پارامتر cls در کلاس پایتون چیست ؟
در بخشهای قبلی اشاره شد که در متدهای نمونه کلاس، از پارامترselfبه منظور دسترسی به متغیرهای نمونه استفاده میشود. این پارامتر در اعلان متد نمونه کلاس، به عنوان اولین پارامتر لحاظ میشود که به شی ساخته شده اشاره دارد. همانند پارامترself، پارامترclsنیز اولین پارامتر متد کلاس در نظر گرفته میشود که با استفاده از آن میتوان به متغیرهای کلاس دسترسی داشت. به عبارتی، این پارامتر به کلاس ساخته شده اشاره دارد.
میتوان نام این پارامتر را تغییر داد اما به منظور خوانایی بیشتر برنامه، بهتر است از همان عبارت cls استفاده شود. خاطرنشان میشود که در متدهای کلاس صرفاً میتوان از متغیرهای کلاس استفاده کرد و در این نوع متدها نمیتوان به متغیرهای نمونه کلاس دسترسی داشت.
متد ایستا در کلاس پایتون
متدهای ایستا، متدهایی هستند که از آنها برای تغییر مقادیر ویژگیهای کلاس استفاده نمیشود. به عبارتی، این متدها بهصورت خودکفا عمل میکنند و تنها با دادههایی سروکار دارند که توسط شی مستقیماً به آنها ارسال میشوند؛ البته این نوع متدها میتوانند بدون پارامتر ورودی نیز تعریف شوند. بدینترتیب، در بین پارامترهای آنها، پارامترهایselfوclsدیده نمیشوند. برای دسترسی به این متدها میتوان از نام کلاس یا شی استفاده کرد.
پایتون متدهایی را که در کلاس ایجاد میشوند، بهطور پیشفرض از نوع متد نمونه در نظر میگیرد. به منظور ساخت متدهای ایستا در پایتون باید از دکوراتور@staticmethodو تابعstaticmethod()استفاده کرد تا نوع متد مستقیماً به پایتون اعلام شود. در ادامه، به توضیح هر دو روش ذکر شده برای ساخت متد ایستا پرداخته میشود.
تعریف متد ایستا با استفاده از دکوراتور
برای ایجاد متد ایستا در پایتون، میتوان پیش از اعلان متد از دکوراتور@staticmethodاستفاده کرد. این دکوراتور به عنوان یک تابع توکار در پایتون محسوب میشود. در قطعه کد زیر، مثالی از نحوه ساخت متد ایستا با استفاده از این روش ارائه شده است.
1class Employee(object):
2
3 def __init__(self, name, salary, project_name):
4 self.name = name
5 self.salary = salary
6 self.project_name = project_name
7
8 @staticmethod
9 def gather_requirement(project_name):
10 if project_name == 'ABC Project':
11 requirement = ['task_1', 'task_2', 'task_3']
12 else:
13 requirement = ['task_1']
14 return requirement
15
16 # instance method
17 def work(self):
18 # call static method from instance method
19 requirement = self.gather_requirement(self.project_name)
20 for task in requirement:
21 print('Completed', task)
22
23emp = Employee('Kelly', 12000, 'ABC Project')
24emp.work()
در قطعه کد فوق، متدgather_requirementاز نوع متد ایستا است که به عنوان ورودی پارامترproject_nameرا دریافت میکند و تمامی نیازمندیهای لازم برای تکمیل پروژه را در خروجی بازمیگرداند. خروجی قطعه کد فوق در ادامه ملاحظه میشود:
Completed task_1 Completed task_2 Completed task_3
تعریف متد ایستا با استفاده از تابع Staticmethod
روش دیگری که از آن میتوان به منظور ایجاد متد ایستا در پایتون استفاده کرد، تابع توکارstaticmethod()است. ورودی این تابع، متدی است که در نهایت به متد ایستا تبدیل میشود. به عبارتی، خروجی تابعstaticmethod()، متدی از نوع متد ایستا است. شیوه استفاده از این تابع در ادامه ملاحظه میشود.
1staticmethod(function)
در مثال زیر، قطعه کدی ارائه شده است که نحوه ساخت متد ایستا را با تابعstaticmethod()نشان میدهد. در این مثال، تابعsampleبه عنوان ورودی تابعstaticmethod()در نظر گرفته شده است تا به تابع ایستا تبدیل شود.
1class Employee:
2 def sample(x):
3 print('Inside static method', x)
4
5# convert to static method
6Employee.sample = staticmethod(Employee.sample)
7# call static method
8Employee.sample(10)
متدهای خاص کلاس در زبان پایتون
درون کلاس میتوان به تعریف توابع مختلف با استفاده از کلمه کلیدی def در پایتون پرداخت که هر کدام وظایف خاصی را انجام میدهند و این توابع، متدهای کلاس محسوب میشوند. علاوهبر توابع تعریف شده توسط برنامه نویس، پایتون «توابع توکاری» (Built-in Functions) برای کلاسهای تعریف شده در نظر میگیرد. این توابع، «توابع | متدهای خاص» (Special Functions | Special Methods) نام دارند و با علامت__ مشخص میشوند که در ادامه به فهرستی از آنها اشاره شده است:
- تابع__init__
- تابع__str__
- تابع__len__
- تابع__eq__
در ادامه مطلب، به توضیح کاربرد هر یک از توابع توکار ذکر شده در فوق به همراه مثال پرداخته میشود.
تابع __init__ پایتون در کلاس
تابع__init__ در پایتون یکی از متدهای توکار کلاس محسوب میشود. در هنگام ساخت شی از یک کلاس، تابع__init__بهصورت خودکار صدا زده شده و دستورات داخل این تابع اجرا میشوند. این تابع به عنوان تابع «سازنده» (Constructor) در زبان برنامه نویسی پایتون به حساب میآید. معمولاً در داخل تابع__init__متغیرهای کلاس، مقداردهی اولیه میشوند.
به منظور تعریف این تابع، میتوان همانند سایر توابع، از کلمه کلیدیdef استفاده کرد. همچنین، مانند دیگر توابع در پایتون، اولین پارامتر این متد، پارامترselfاست که به شی ساخته شده اشاره دارد. سایر پارامترها نیز پس از پارامترselfقرار میگیرند. در مثال زیر، نمونهای از نحوه کاربرد تابع__init__در پایتون ملاحظه میشود.
1class IntellipaatClass:
2 def __init__(self, course):
3 self.course = course
4 def display(self):
5 print(self.course)
6object1 = IntellipaatClass("Python")
7object1.display()
در مثال فوق، به محض ساخته شدن شیobject1با دستورobject1 = IntellipaatClass("Python") ، تابع__init__به عنوان تابع سازنده، بهطور خودکار فراخوانده میشود. در پی فراخوانی این تابع، شیobject1و مقدارPythonبه پارامترهایself وcourse ارسال میشوند. به متغیرcourseمیتوان در توابع دیگر داخل کلاس نیز دسترسی داشت. در مثال ذکر شده در فوق، تابعی با نامdisplayساخته شده است که مقدار متغیرcourseرا در خروجی نشان میدهد.
تابع __str__ در کلاس پایتون
تابع__str__به عنوان یک تابع توکار در کلاس پایتون بهمنظور چاپ مقداری در خروجی استفاده میشود. مثال زیر را در نظر بگیرید؛ در این مثال، کلاسی با نامBook دارای تابع توکار__init__ است که سه متغیرname،writerوpagesرا به هنگام ساخت شی از این کلاس، مقداردهی اولیه میکند. شیئی با نامbنیز از این کلاس ساخته میشود که سه مقدار مشخص شده را به پارامترهای تابع__init__ارسال میکند.
1class Book():
2 def __init__(self, name, writer, pages):
3 self.name = name
4 self.writer = writer
5 self.pages = pages
6
7b = Book("Moby Dick", "Herman Melville", "378")
8print(b)
چنانچه قطعه کد فوق اجرا شود، خروجی بهصورت زیر خواهد بود:
<__main__.Book object at 0x7f9ed5b1d590>
به عبارتی، زمانی که با دستورprint(b) بخواهیم اطلاعاتی درباره شیb از کلاسBookرا چاپ کنیم، در خروجی، اطلاعاتی درباره کلاس شی و محل ذخیرهسازی شی در حافظه نشان داده میشوند. چنانچه لازم باشد با دستورprint(b)، اطلاعاتی راجع به کلاس یا پارامترهای آن در خروجی چاپ شوند، از تابع__str__استفاده میشود. در مثال زیر، نحوه تعریف تابع__str__به عنوان یکی دیگر از متدهای کلاس نشان داده شده است.
1class Book():
2 def __init__(self, name, writer, pages):
3 self.name = name
4 self.writer = writer
5 self.pages = pages
6
7 def __str__(self):
8 return f"The title of the book is {self.name}"
9
10b = Book("Moby Dick", "Herman Melville", "378")
11print(b)
خروجی قطعه کد فوق در ادامه ملاحظه میشود:
The title of the book is Moby Dick
تابع __len__ در کلاس پایتون
از تابع__len__به منظور بازگرداندن طول یکی از ویژگیهای کلاس استفاده میشود. این متد معادل تابعlen()است. چنانچه تابع__len__در کلاس اعلان نشده باشد و کاربر این تابع را با استفاده از شی ساخته شده فراخوانی کند، خطایی در خروجی ظاهر میشود که گویای آن است چنین تابعی برای شی وجود ندارد. بدینترتیب، تابع__len__برخلاف تابع__str__مقدار پیشفرضی در خروجی بازنمیگرداند.
در مثال زیر، قطعه کدی از پایتون ملاحظه میشود که در آن تابع__len__طول مقدار پارامترaرا در خروجی برمیگرداند. خاطرنشان میشود که برای بازگرداندن طول پارامتر میتوان از دو دستورobj.__len__یاlen()استفاده کرد.
1class GFG:
2 def __init__(self, a):
3 self.a = a
4 def __len__(self):
5 return len(self.a)
6
7obj = GFG("GeeksForGeeks")
8print(len(obj))
خروجی قطعه کد فوق در ادامه ملاحظه میشود:
13
تابع __eq__ در کلاس پایتون
از تابع__eq__در پایتون به منظور مقایسه دو نمونه از کلاس استفاده میشود. شروط مقایسه را میتوان در داخل این متد مشخص کرد. در قطعه کد زیر، مثالی از نحوه کاربرد تابع__eq__به منظور مقایسه دو شی از کلاسBookملاحظه میشود.
1class Book():
2 def __init__(self, name, writer, pages):
3 self.name = name
4 self.writer = writer
5 self.pages = pages
6
7 def __eq__(self, other):
8 return (self.name == other.name) & (self.writer == other.writer)
9
10b = Book("Moby Dick", "Herman Melville", "378")
11a = Book("Moby Dick", "Herman Melville", "410")
12print(b == a)
در قطعه کد فوق، دو شی با نامهایbوaاز کلاسBookساخته شدهاند که ویژگیهای نام کتاب و نام نویسنده این دو شی با یکدیگر برابر هستند. در تابع__eq__نیز ویژگیهای این دو شی مورد مقایسه قرار گرفتهاند. در صورت یکسان بودن مقادیر ویژگیها، خروجی قطعه کد فوق برابر با True خواهد بود در غیر این صورت مقدار False در خروجی نشان داده میشود.
انواع کلاس در زبان برنامه نویسی پایتون
در زبان برنامه نویسی پایتون انواع مختلفی از کلاس وجود دارند که هنگام نوشتن کلاس در پایتون باید نوع آن را مشخص کرد. در ادامه، انواع کلاس در این زبان فهرست شدهاند:
- «کلاس انتزاعی» (Abstract Class)
- «کلاس عینی» (Concrete Class)
- «کلاس جزئی» (Partial Class)
در بخشهای بعدی مطلب حاضر، به توضیح هر یک از انواع کلاسهای پایتون پرداخته میشود.
کلاس انتزاعی در پایتون
کلاس انتزاعی به کلاسی گفته میشود که شامل «متدهای انتزاعی» (Abstract Method) باشد. متدهای انتزاعی، متدهایی هستند که صرفاً اعلان شدهاند اما بدنه آنها تعریف نشده است. کلاسهای انتزاعی زمانی کاربرد دارند که تیم بزرگی از برنامه نویسان به توسعه پروژه بپردازند و برای توابعی با نامهای یکسان، دستورات متفاوتی را تعریف کنند.
به منظور استفاده از کلاسهای انتزاعی، نمیتوان بهطور مستقیم از آنها شی ساخت. به عبارتی، باید کلاسهای فرزندی را ایجاد کرد که از کلاسهای انتزاعی ارثبری میکنند و سپس با تعریف اشیای جدید از کلاسهای فرزند، بتوان به متدهای انتزاعی کلاسهای انتزاعی دسترسی داشت.
برای تعریف کلاس انتزاعی در زبان پایتون، از کتابخانهabc استفاده میشود. از این کتابخانه، باید ماژولABC برای تعریف یک کلاس در پایتون فراخوانی شود. دستور abc.abstractmethod نیز برای تعریف متد انتزاعی کاربرد دارد. در مثال زیر، نحوه ساخت کلاس انتزاعی در پایتون ملاحظه میشود.
1From abc import ABC, abstractmethod
2Class AbstractClassName(ABC):
3 @abstract method
4 def abstract_method_name(self):
5 Pass
کلاس عینی در پایتون
کلاس عینی به کلاسی گفته میشود که تمامی متدهای آن دارای مجموعهای از دستورات هستند. کلاسهای عادی، نوعی کلاس عینی محسوب میشوند که میتوان با تعریف شی از این کلاسها، به مشخصههای کلاس دسترسی داشت. همچنین، کلاسهای فرزندی که از کلاسهای انتزاعی ارثبری میکنند، به عنوان کلاسهای عینی تلقی میشوند.
کلاس جزئی در پایتون
کلاس جزئی در پایتون این امکان را به کاربران میدهد تا فایل یک کلاس را به چندین بخش مختلف تقسیم و این بخشها را در فایلهای مختلف بهصورت جداگانه ذخیره کرد. در زمان کامپایل، بهصورت خودکار تمامی فایلهای مربوط به یک کلاس با یکدیگر ترکیب میشوند.
زمانی که برنامه نویسان مختلفی بر روی یک پروژه بزرگ نرمافزاری کار میکنند، نوشتن کلاس جزئی در پایتون این امکان را برای آنها فراهم میکند تا بر روی اجزای یک کلاس واحد، کار کنند و متدهای آن را گسترس دهند. به عبارتی، با استفاده از کلاسهای جزئی میتوان بدون نیاز به ساخت مجدد کلاس، به تکمیل و توسعه اجزای کلاس در فایلهای جداگانه پرداخت.
کلاس فرزندی که از کلاس جزئی ارثبری میکند، از تمام اجزای جداگانه آن ارث میبرد. همچنین، اگر بخشی از کلاس جزئی دارای متد انتزاعی باشد، کل کلاس به عنوان کلاس انتزاعی محسوب میشود.
کاربرد دستور Pass در پایتون برای ساخت کلاس چیست ؟
زمانی که برنامه نویس، کلاسی را اعلان کرده باشد و بخواهد نوشتن دستورات داخل کلاس را به زمان دیگری موکول کند، میتواند از دستورpassبه جای کلیه دستورات کلاس استفاده کند. در صورتی که بدنه کلاس خالی باشد، در زمان کامپایل برنامه، خطا رخ میدهد. به عبارتی، دستورpass، خروجی خاصی ندارد و صرفاً در زمان اجرای برنامه، از بروز خطا جلوگیری میکند.
از دستورpassمیتوان برای تمامی ساختارهایی نظیر حلقهها، توابع، دستورات شرطی و کلاس استفاده کرد که دارای بدنه هستند. در ادامه، مثالی از نحوه کاربرد دستورpassدر کلاس پایتون ملاحظه میشود.
1class Person:
2 pass
پیاده سازی شی گرایی با کلاس در زبان برنامه نویسی پایتون
همانطور که در بخشهای قبلی گفته شد، پایتون به عنوان یکی از زبانهای برنامه نویسی شیگرایی محسوب میشود. شی و کلاس اجزای مهم در شیگرایی هستند که از آنها میتوان برای پیادهسازی اصول شیگرایی استفاده کرد. این اصول عبارتاند از:
- «اصل وراثت» (Inheritance Principle)
- «اصل کپسولهسازی» (Encapsulation Principle)
- «اصل انتزاع» (Abstraction Principle)
- «اصل چندریختی | پلی مورفیسم» (Polymorphism Principle)
در ادامه، به نحوه استفاده از کلاس در پیادهسازی این چهار اصل شیگرایی پرداخته میشود.
ارث بری کلاس در پایتون
بر اساس اصل وراثت، یک کلاس میتواند به عنوان «کلاس فرزند | زیر کلاس» (Child Class | Sub Class) مشخصههای خود را از مشخصههای کلاس دیگری با عنوان «کلاس والد | ابر کلاس | کلاس پایه» (Parent Class | Super Class | Base Class) به ارث ببرد. وراثت در برنامه نویسی باعث افزایش خوانایی کدهای برنامه شده و مانع از نوشتن کدهای تکراری میشود. با توجه به ساختار ارثبری کلاسها، انواع مختلفی از وراثت وجود دارند که در ادامه فهرستی از آنها ملاحظه میشود:
- «وراثت منفرد» (Single Inheritance)
- «وراثت چندگانه» (Multiple Inheritance)
- «وراثت چند سطحی» (Multi-Level Inheritance)
- «وراثت سلسلهمراتبی» (Hierarchical Inheritance)
- «وراثت ترکیبی» (Hybrid Inheritance)
در ادامه به توضیح هر یک از انواع وراثت کلاسها در پایتون به همراه مثال پرداخته میشود.
وراثت منفرد در پایتون
در این نوع ارثبری، هر کلاس فرزند تنها دارای یک کلاس والد است و تمامی ویژگیها و متدهای کلاس والد را به ارث میبرد. در مثال زیر، شیوه ارثبری کلاس فرزند از کلاس والد ملاحظه میشود.
1class Intellipaat:
2 def course(self):
3 print("Python tutorial")
4class hello(Intellipaat):
5 def func(self):
6 print("Welcome to intellipaat")
7ob1 = hello()
8ob1.func()
9ob1.course()
در مثال فوق، دو کلاس با نامهایIntellipaat وhello وجود دارند. به منظور تبدیل کردن کلاسhelloبه کلاس فرزند، کافی است نام کلاس والد، در قسمت اعلان کلاس در قسمت پرانتز نوشته شود. در این مثال، با استفاده از دستورclass hello(Intellipaat) ، کلاسhelloاز کلاس والد خود، یعنی کلاسIntellipaat، ارثبری میکند. به عبارتی، کلاسhelloمتدcourseرا از کلاسIntellipaatبه ارث میبرد و در نهایت دارای دو متدcourseوfuncاست. بدینترتیب، شیئی که از کلاسhelloساخته میشود، میتواند به دو متدcourseوfuncدسترسی داشته باشد. خروجی قطعه کد فوق در ادامه ملاحظه میشود:
Welcome to Intellipaat Python tutorial
وراثت چندگانه در پایتون
در این نوع ارثبری، هر کلاس فرزند میتواند دارای بیش از یک کلاس والد باشد. به عبارتی، کلاس فرزند تمامی مشخصههای مربوط به کلاسهای والد خود را به ارث میبرد. به منظور ایجاد وراثت چندگانه در پایتون، کافی است در زمان اعلان کلاس فرزند، نام تمامی کلاسهای والد در داخل پرانتز نوشته شوند. در ادامه، مثالی از نحوه ایجاد وراثت چندگانه در پایتون ملاحظه میشود.
1class BaseClass1():
2 def __init__(self):
3 print("Base class 1")
4class BaseClass2():
5 def __init__(self):
6 print("Base class 2")
7class derivedClass (BaseClass1, BaseClass2):
8 def __init__(self):
9 BaseClass1.__init__(self)
10 BaseClass2.__init__(self)
11 print("derived class")
12 def display_all(Self):
13 print(self.ob1, self.ob2)
14ob = derivedClass()
در مثال فوق، دو کلاسBaseClass1 وBaseClass2کلاسهای والد برای کلاسderivedClassهستند و با استفاده از دستور class derivedClass (BaseClass1, BaseClass2) ، ارثبری چندگانه ایجاد شده است. بدینترتیب، شی ساخته شده از کلاسderivedClass، به تمامی متدهای دو کلاسBaseClass1وBaseClass2دسترسی دارد. خروجی قطعه کد فوق، در ادامه ملاحظه میشود:
Base class 1 Base Class 2 derived class
وراثت چندسطحی در پایتون
در این نوع وراثت، کلاس فرزند، از کلاس والدی ارثبری میکند که آن کلاس، به عنوان کلاس فرزند، از کلاس والد دیگری ارث میبرد. به عبارتی، کلاس فرزند، از تمامی مشخصههای کلاس والد و کلاس والد والد خود ارثبری میکند. در مثال زیر، نمونهای از ساخت وراثت چندسطحی در پایتون ملاحظه میشود.
1class BaseClass():
2 def __init__(self):
3 print("Base class")
4class childClass(BaseClass):
5 def __init__(self):
6 print("Child class")
7class grandchildClass(childClass):
8 def __init__(self):
9 BaseClass.__init__(self)
10 childClass.__init__(self)
11 print("Grand child class")
12ob1 = grandchildClass()
در مثال فوق، کلاسBaseClassکلاس والد برایchildClassاست و کلاسgrandchildClassاز کلاسchildClassارثبری میکند. بدینترتیب، کلاسgrandchildClassتمامی مشخصههای هر دو کلاسBaseClassوchildClassرا به ارث میبرد. خروجی قطعه کد فوق در ادامه ملاحظه میشود:
Base class Child class Grand child class
وراثت سلسله مراتبی در پایتون
در این نوع وراثت، ساختار ارثبری کلاسها بهصورت سلسلهمراتبی است. به عبارتی، یک کلاس والد وجود دارد که تمامی کلاسهای فرزند از آن ارثبری میکنند. در مثال زیر، نحوه ایجاد وراثت سلسلهمراتبی در پایتون ملاحظه میشود.
1# Python code to demonstrate example of
2# hierarchical inheritance
3
4class Details:
5 def __init__(self):
6 self.__id="<No Id>"
7 self.__name="<No Name>"
8 self.__gender="<No Gender>"
9 def setData(self,id,name,gender):
10 self.__id=id
11 self.__name=name
12 self.__gender=gender
13 def showData(self):
14 print("Id: ",self.__id)
15 print("Name: ", self.__name)
16 print("Gender: ", self.__gender)
17
18class Employee(Details): #Inheritance
19 def __init__(self):
20 self.__company="<No Company>"
21 self.__dept="<No Dept>"
22 def setEmployee(self,id,name,gender,comp,dept):
23 self.setData(id,name,gender)
24 self.__company=comp
25 self.__dept=dept
26 def showEmployee(self):
27 self.showData()
28 print("Company: ", self.__company)
29 print("Department: ", self.__dept)
30
31class Doctor(Details): #Inheritance
32 def __init__(self):
33 self.__hospital="<No Hospital>"
34 self.__dept="<No Dept>"
35 def setEmployee(self,id,name,gender,hos,dept):
36 self.setData(id,name,gender)
37 self.__hospital=hos
38 self.__dept=dept
39 def showEmployee(self):
40 self.showData()
41 print("Hospital: ", self.__hospital)
42 print("Department: ", self.__dept)
43
44def main():
45 print("Employee Object")
46 e=Employee()
47 e.setEmployee(1,"Prem Sharma","Male","gmr","excavation")
48 e.showEmployee()
49 print("nDoctor Object")
50 d = Doctor()
51 d.setEmployee(1, "pankaj", "male", "aiims", "eyes")
52 d.showEmployee()
53
54if __name__=="__main__":
55 main()
در مثال فوق، سه کلاس با نامهایDetails،EmployeeوDoctorساخته شدهاند که کلاسDetails به عنوان کلاس والد برای کلاسهایEmployee وDoctor محسوب میشود. خروجی قطعه کد فوق در ادامه ملاحظه میشود:
Employee Object Id: 1 Name: Prem Sharma Gender: Male Company: gmr Department: excavation Doctor Object Id: 1 Name: pankaj Gender: male Hospital: aiims Department: eyes
وراثت ترکیبی در زبان پایتون
این نوع وراثت، ترکیبی از روشهای ارثبری مختلف است که در بخشهای قبلی به آنها اشاره شد. به عبارتی، میتوان انواع روشهای وراثت را با یکدیگر ترکیب کرد تا بتوان از حالات مختلف ارثبری بهره برد. به عنوان مثال، طبق تصویر زیر میتوان وراثت سلسله مراتبی را با وراثت چندگانه ترکیب کرد.
در قطعه کد زیر، نحوه ایجاد وراثت ترکیبی در پایتون ملاحظه میشود. در این مثال، کلاسUniversityکلاس والد برای دو کلاسCourseوBranchاست و کلاسStudentنیز فرزند دو کلاسCourseوBranchمحسوب میشود که از کلاسUniversityنیز ارثبری میکند.
1# Creating a Base class named University:
2class University:
3 def __init__(self):
4 print("Contructor of the Base class")
5 # Initializing a class variable named univ to store university name:
6 self.univ = "MIT"
7 def display(self): # Method to print the University Name:
8 print(f"The University name is: {self.univ}")
9
10# 1st Derived or Child Class of University Class:
11class Course(University):
12 def __init__(self):
13 # using "super" keyword to access members of the parent class having same name:
14 print("Constructor of the Child Class 1 of Class University")
15 University.__init__(self)
16 self.course = "CSE"
17 def display(self): # Method to print the Course Name:
18 # using "super" keyword to access display method defined in the parent class:
19 print(f"The Course name is: {self.course}")
20 University.display(self)
21
22# 2nd Derived or Child Class of University Class:
23class Branch(University):
24 def __init__(self):
25 print("Constructor of the Child Class 2 of Class University")
26 self.branch = "Data Science"
27 def display(self): # Method to print the Branch Name:
28 print(f"The Branch name is: {self.branch}")
29
30# Derived or Child Class of Class Course and Branch:
31class Student(Course, Branch):
32 def __init__(self):
33 print("Constructor of Child class of Course and Branch is called")
34 self.name = "Tonny"
35 Branch.__init__(self)
36 Course.__init__(self)
37 def display(self):
38 print(f"The Name of the student is: {self.name}")
39 Branch.display(self)
40 Course.display(self)
41
42# Object Instantiation:
43ob = Student() # Object named ob of the class Student.
44print()
45ob.display() # Calling the display method of Student class.
خروجی قطعه کد فوق در ادامه ملاحظه میشود:
Constructor of Child class of Course and Branch is called Constructor of the Child Class 2 of Class University Constructor of the Child Class 1 of Class University Contructor of the Base class The Name of the student is: Tonny The Branch name is: Data Science The Course name is: CSE The University name is: MIT
متد super کلاس در پایتون
از متدsuper()در پیادهسازی اصل وراثت و به منظور دسترسی به کلاس والد از داخل کلاس فرزند استفاده میشود. این متد پارامتر ورودی ورودی دریافت نمیکند و از تکرار نام کلاس والد جلوگیری میکند. پس از متدsuper()، نام متدی از کلاس والد نوشته میشود که بنا است در کلاس فرزند استفاده شود. در قطعه کد زیر، مثالی از نحوه کاربرد این متد در پایتون ارائه شده است.
1class Food():
2 def __init__(self, name):
3 self.name = nameا
4class Cheese(Food):
5 def __init__(self, brand):
6 super().__init__()
7 self.brand = brand
در قطعه کد فوق، کلاسFoodبه عنوان کلاس والد برای کلاسCheeseمحسوب میشود. با استفاده از دستورsuper().__init__()، متد__init__از کلاسFoodفراخوانده شده است.
کپسوله سازی کلاس در زبان برنامه نویسی پایتون چیست ؟
کپسولهسازی یکی از چهار اصل شیگرایی محسوب میشود که میتوان با استفاده از آن، دسترسی به مشخصههای کلاس را مدیریت کرد. به عبارتی، با به کارگیری این اصل میتوان برای ویژگیها و متدهای کلاس، محدودیت دسترسی ایجاد کرد تا نتوان آنها را از خارج کلاس و حتی از طریق کلاسهای فرزند، تغییر داد. همچنین، این اصل بستری را فراهم میکند تا تمامی مشخصههای اشیا درون کلاس در کنار هم قرار گیرند که همین امر باعث میشود نوشتن کدها بهصورت سازمانیافته انجام شوند. در ادامه، به نحوه کپسولهسازی مشخصههای کلاس با ذکر مثال پرداخته میشود.
ساخت متد خصوصی در پایتون
چنانچه بخواهیم مثال ملموسی درباره کپسولهسازی در دنیای واقعی ارائه کنیم، میتوان از موتور ماشین یاد کرد که شامل اجزای مختلفی مانند شمع، سوپاپ و پیستون است. هیچ رانندهای بهطور مستقیم از اجزای موتور استفاده نمیکند. با این حال، هر یک از این اجزاء، وظیفهای را برعهده دارند که با انجام آن، موتور ماشین بهدرستی شروع به کار میکند. در دنیای برنامه نویسی شی گرا، وظایف هر یک از این اجزاء، به عنوان «متد خصوصی» (Private Method) برای کلاس موتور ماشین محسوب میشوند.
در برنامه نویسی، مستقیماً نمیتوان به متدهای خصوصی از خارج کلاس یا از طریق کلاسهای فرزند دسترسی داشت. به منظور تعریف متدهای خصوصی، پیش از نام متد، از علامت (__) در پایتون استفاده میشود. البته باید خاطرنشان کرد که پایتون، مانع استفاده از متد خصوصی خارج از کلاس نمیشود. به عبارتی، چنانچه از این متدها در خارج از کلاس، استفاده شوند، خطای کامپایلر رخ نمیدهد و تعریف متدهای خصوصی در پایتون فقط به سایر برنامه نویسان نشان میدهد که این متدها برای داخل کلاس استفاده میشوند. به بیان دیگر، استفاده از علامت (__) قراردادی برای تعیین نام متدهای خصوصی در میان برنامه نویسان است.
در مثال زیر، نحوه تعریف متد خصوصی در کلاس پایتون ملاحظه میشود. در این مثال، کلاسPersonدارای یک تابع سازنده__init__و دو متدrunو__warmupاست که متدrunاز نوع متد «عمومی» و متد__warmupاز نوع متد خصوصی است.
1class Person:
2 def __init__(self, name):
3 self.name = name
4
5 def run(self):
6 self._warmup()
7 print("{} is running".format(self.name))
8
9 def _warmup(self):
10 print("{} is warming up".format(self.name))
11
12jack = Person('Jack')
13jack.run()
با اجرای قطعه کد فوق، خروجی زیر حاصل میشود:
Jack is warming up Jack is running
حال، چنانچه با استفاده از شیjackاز بیرون کلاس، بخواهیم به متد خصوصی__warmupدسترسی داشته باشیم، قطعه کد فوق را بهصورت زیر تغییر میدهیم:
1class Person:
2 def __init__(self, name):
3 self.name = name
4
5 def run(self):
6 self._warmup()
7 print("{} is running".format(self.name))
8
9 def _warmup(self):
10 print("{} is warming up".format(self.name))
11
12jack._warmup()
خروجی قطعه کد فوق در ادامه ملاحظه میشود:
Jack is warming up
همانطور که ملاحظه شد، با فراخوانی متد خصوصی از خارج کلاس، هیچ خطای کامپایلری صورت نگرفت.
ساخت ویژگی خصوصی در پایتون
به منظور ساخت ویژگیهای خصوصی کلاس در پایتون نیز همانند متدهای خصوصی، از علامت (__) پیش از نام ویژگی استفاده میشود. البته باید خاطرنشان کرد که این علامت، قراردادی برای نشانهگذاری ویژگیهای خصوصی در میان برنامه نویسان است و همانند متدهای خصوصی کلاس، میتوان از خارج کلاس به ویژگیهای خصوصی کلاس دسترسی داشت.
در ادامه، مثالی از تعریف ساخت ویژگی خصوصی در کلاس ملاحظه میشود. در این مثال، در تابع سازنده__init__، دو متغیر (ویژگی) با نامهایnameوemailایجاد شدهاند که ویژگیnameاز نوع ویژگی عمومی و ویژگیemailاز نوع ویژگی خصوصی هستند.
1class Person:
2 def __init__(self, name, email):
3 self.name = name
4 self._email = email
5
6mark = Person("Mark", "mark@domain.com")
7print(mark.name)
8print(mark._email)
خروجی قطعه کد فوق در ادامه ملاحظه میشود. بر اساس خروجی حاصل شده، با استفاده از شیmarkمیتوان به ویژگی خصوصی کلاس دسترسی داشت و هیچ گونه خطای کامپایلری در این باره رخ نمیدهد.
Mark mark@domain.com
انتزاع در کلاس پایتون
انتزاع با کپسولهسازی رابطه بسیار نزدیکی دارد. از کپسولهسازی برای قرار دادن ویژگیها و متدها در داخل کلاس استفاده میشود که با بهکارگیری آن، تمامی اطلاعات مرتبط با یک شی در کنار هم قرار میگیرند. انتزاع مسئولیت کنترل دسترسی به ویژگیها و متدهای داخل کلاس انتزاعی را برعهده دارد و اطلاعات آن را از کاربران پنهان میکند.
به منظور تعریف کلاس انتزاع از ماژولABCاستفاده میشود. همچنین، برای تعریف متد انتزاعی از دکوراتور@abstractmethodمیتوان استفاده کرد. برای دسترسی به ماژولABCو دکوراتور@abstractmethod، میتوان کتابخانهabcرا فراخوانی کرد. خاطرنشان میشود نمیتوان مستقیماً از کلاس انتزاعی، شی ساخت. برای استفاده از کلاس انتزاعی، باید از کلاس فرزند استفاده کرد که از کلاس انتزاعی ارثبری میکند و سپس با استفاده از شی ساخته شده از کلاس فرزند، میتوان به متدهای کلاس انتزاعی دسترسی داشت. قطعه کد زیر، مثالی از نحوه ساخت کلاس و متد انتزاعی را نشان میدهد.
1# Python program demonstrate
2# abstract base class work
3from abc import ABC, abstractmethod
4class Car(ABC):
5 @abstractmethod
6 def mileage(self):
7 pass
8
9class Tesla(Car):
10 def mileage(self):
11 print("The mileage is 30kmph")
12class Suzuki(Car):
13 def mileage(self):
14 print("The mileage is 25kmph ")
15class Duster(Car):
16 def mileage(self):
17 print("The mileage is 24kmph ")
18
19class Renault(Car):
20 def mileage(self):
21 print("The mileage is 27kmph ")
22
23# Driver code
24t= Tesla ()
25t.mileage()
26
27r = Renault()
28r.mileage()
29
30s = Suzuki()
31s.mileage()
32d = Duster()
33d.mileage()
در مثال فوق، کلاسCarنوعی کلاس انتزاعی است که یک متد انتزاعی با نامmileageدارد که انتزاعی بودن آن با دکوراتور@abstractmethodمشخص شده است. از پارامترABCدر قسمت اعلان کلاس نیز استفاده میشود تا مشخص کند این کلاس، از نوع کلاس انتزاع است. همچنین، به منظور استفاده از کلاس انتزاعی Car، چند کلاس فرزند با نامهایTelsa،Suzuki،DusterوRenaultساخته شدهاند که از کلاس ارثبری میکنند. در هر یک از این کلاسها بدنه متدmileageبا دستورات متفاوت تعریف میشوند. خروجی قطعه کد فوق در ادامه ملاحظه میشود:
The mileage is 30kmph The mileage is 27kmph The mileage is 25kmph The mileage is 24kmph
چندریختی در برنامه نویسی
«چندریختی | پلی مورفیسم» (Polymorphism) یکی از اصول مهم برنامه نویسی شیگرایی است و به وضعیتی اتلاق میشود که ماهیتی نظیر متد، «عملگر» (Operator) یا شی در شرایط مختلف، رفتار متفاوتی داشته باشند.
به منظور درک بهتر این مفهوم میتوان از مثال ملموسی در دنیای واقعی استفاده کرد. میتوان شخصی را در نظر گرفت که دارای جایگاههای مختلف اجتماعی است. به عبارتی، این فرد به دلیل داشتن فرزند، رابطه پدری و همچنین رابطه همسری با فرزند و همسر خود دارد.
همچنین، این شخص دارای یک خواهر است و بدینترتیب رابطه برادری با خواهر خود و رابطه فرزندی با والدین خود دارد. بهعلاوه، این شخص کارمند شرکتی است که با همتیمیهای خود رابطه همکار دارد. بدینترتیب، این شخص در شرایط مختلف و در رابطه با اطرافیان خود، دارای جایگاه اجتماعی منحصربفردی است. به این حالت، چندریختی یا پلی مورفیسم گفته میشود.
اصل چندریختی دارای مزیتهای مختلفی است که در ادامه به مهمترین آنها اشاره شده است:
- اصل چندریختی مانع نوشتن کدهای تکراری میشود و میتوان از قطعه کدهای نوشته شده به دفعات استفاده کرد.
- اصل پلی مورفیسم باعث میشود خطایابی قطعه کدها راحتتر انجام شود.
- با استفاده از اصل چندریختی میتوان از متغیرهای تعریف شده برای ذخیرهسازی دادهها با نوع داده مختلف استفاده کرد.
از اصل چندریختی میتوان در بخشهای مختلف برنامه نویسی استفاده کرد. در این بخش، صرفاً به کاربرد این اصل در نوشتن کلاس در پایتون پرداخته میشود.
چندریختی کلاس در زبان برنامه نویسی پایتون
زبان برنامه نویسی پایتون به کاربران این اجازه را میدهد که در کلاسهای تعریف شده، متدهایی با نامهای یکسان ایجاد کنند. در این حالت، میتوان از هر شی ساخته شده به منظور دسترسی به متدهایی با نام مشابه استفاده کرد. در ادامه، مثالی از نحوه کاربرد اصل چندریختی در ایجاد کلاس در پایتون ملاحظه میشود.
1
2class Tiger():
3 def nature(self):
4 print('I am a Tiger and I am dangerous.')
5
6 def color(self):
7 print('Tigers are orange with black strips')
8
9class Elephant():
10 def nature(self):
11 print('I am an Elephant and I am calm and harmless')
12
13 def color(self):
14 print('Elephants are grayish black')
15
16obj1 = Tiger()
17obj2 = Elephant()
18
19for animal in (obj1, obj2): # creating a loop to iterate through the obj1 and obj2
20 animal.nature()
21 animal.color()
بر اساس قطعه کد فوق، دو کلاس با نامهایTigerوElephantایجاد شدهاند که هر دو کلاس دارای متدهایnatureوcolorهستند. با ساخت دو شیobj1وobj2از دو کلاسTigerوElephant، میتوان با استفاده از یک حلقهfor، متدهای هر یک از دو کلاس را فراخوانی کرد. به عبارتی، اصل چندریختی این امکان را فراهم میکند تا با نوشتن قطعه کد کمتر، به متدهای هر دو کلاس دسترسی داشت. خروجی قطعه کد فوق در ادامه ملاحظه میشود:
I am a Tiger and I am dangerous. Tigers are orange with black strips I am an Elephant and I am calm and harmless Elephants are grayish black
رابطه چندریختی و وراثت در پایتون (بازنویسی متد)
اصل چندریختی با مفهوم وراثت رابطه بسیار نزدیکی دارد. در زبان پایتون زمانی که کلاس فرزندی از کلاس والد ارثبری میکند، تمامی مشخصههای کلاس والد در کلاس فرزند قابل دسترس هستند.
گاهی نیاز است در کلاس فرزند، متدی همنام با متد کلاس والد ایجاد شود به طوری که این متد شامل دستوراتی مغایر با دستورات متد کلاس والد باشد. به چنین حالتی، «بازنویسی متد» (Method Overriding) گفته میشود که اصل چندریختی این امکان را برای کلاس فراهم کرده است. در ادامه، مثالی از نحوه کاربرد اصل چندریختی و مفهوم بازنویسی متد ارائه شده است.
1
2class Vehicle:
3 def __init__(self, brand, model, price):
4 self.brand = brand
5 self.model = model
6 self.price = price
7
8 def show(self):
9 print('Details:', self.brand, self.model, 'Price:', self.price)
10
11 def max_speed(self):
12 print('Vehicle max speed is 160')
13
14 def gear_system(self):
15 print('Vehicle has 6 shifter gearbox')
16
17# inherit from vehicle class
18class Car(Vehicle):
19 def max_speed(self):
20 print('Car max speed is 260')
21
22 def gear_system(self):
23 print('Car has Automatic Transmission')
24
25# Car Object
26car = Car('Audi', 'R8', 9000000)
27car.show()
28# call methods from Car class
29car.max_speed()
30car.gear_system()
31
32# Vehicle Object
33vehicle = Vehicle('Nissan', 'Magnite', 550000)
34vehicle.show()
35# call method from a Vehicle class
36vehicle.max_speed()
37vehicle.gear_system()
در مثال فوق، دو کلاسCarوVehicleایجاد شدهاند که کلاسVehicleبه عنوان کلاس والد برای کلاسCarمحسوب میشود. کلاسCarبه عنوان کلاس فرزند، دو متد با نامهایmax_speedوgear_systemدارد که این متدها همنام با دو متد موجود در کلاس والد هستند. زمانی که با استفاده از شیcarکه نمونهای از کلاس فرزندCarاست، متدهایmax_speedوgear_systemفراخوانی میشوند، بر اساس اصل چندریختی، این دو متد از کلاسCarصدا زده شده و دیگر دستورات متدهای کلاس والدVehicleاجرا نمیشوند. خروجی قطعه کد فوق بهصورت زیر است:
Details: Audi R8 Price: 9000000 Car max speed is 260 Car has Automatic Transmission Details: Nissan Magnite Price: 550000 Vehicle max speed is 160 Vehicle has 6 shifter gearbox
چندریختی زمان کامپایل (سربارگذاری متد)
«سربارگذاری متد» (Method Overloading) زمانی رخ میدهد که کلاس دارای چندین متد با نامهای یکسان باشد. این متدهای همنام در نوع و تعداد آرگومان با یکدیگر مغایرت دارند. در این حالت، روال فراخوانی متدهای همنام، در زمان کامپایل برنامه انجام میشود.
زبان برنامه نویسی پایتون از سربارگذاری متد و چندریختی زمان کامپایل پشتیبانی نمیکند. با این حال، میتوان مثالی از پایتون ارائه کرد که به نوعی این وضعیت را نشان میدهد:
1class Example:
2 def multiply(self,a,b,c=1):
3 print(a*b*c)
4
5example=Example()
6example.multiply(5,10)
7example.multiply(2,5,6)
در مثال فوق ملاحظه میشود که متدmultiplyمیتواند از شیهایی با دو یا سه پارامتر به منظور محاسبه حاصل ضرب پارامترها پشتیبانی کند. خروجی قطعه کد فوق به صورت زیر است:
50 60
فرا کلاس در زبان برنامه نویسی پایتون چیست ؟
در زبان برنامه نویسی پایتون میتوان با استفاده از تابعtype()نوع هر ماهیتی نظیر متغیر، کلاس، شی و ساختار داده را تشخیص داد. در مثال زیر، نحوه کاربرد تابع به منظور تعیین نوع دادههای مختلف ملاحظه میشود.
1num = 23
2print("Type of num is:", type(num))
3
4lst = [1, 2, 4]
5print("Type of lst is:", type(lst))
6
7name = "Atul"
8print("Type of name is:", type(name))
خروجی قطعه کد فوق بهصورت زیر است:
Type of num is: <class 'int'> Type of lst is: <class 'list'> Type of name is: <class 'str'>
بر اساس خروجیهای حاصل شده در بالا، میتوان گفت که هر ماهیتی در زبان برنامه نویسی پایتون، از کلاس ساخته شده است. در زبانهایی نظیر C++ و جاوا، عبارات «عدد صحیح» (Int)، «عدد اعشاری» (Float) و «کاراکتر» (Char) صرفاً نوع داده را مشخص میکنند در حالی که در زبان پایتون، انواع داده به عنوان اشیایی محسوب میشوند که از کلاسهای Int و Str ساخته شدهاند.
بدینترتیب، در پایتون میتوان برای نوع داده جدید، کلاس جدیدی ایجاد کرد و از آن کلاس، شی جدیدی برای تعریف نوع داده جدید ساخت. به عنوان مثال، در قطعه کد زیر شیئی با نامstu_objاز کلاسStudentساخته شده است که با دستورtype(stu_obj)میتوان نوع داده شی را ملاحظه کرد.
1class Student:
2 pass
3stu_obj = Student()
4
5# Print type of object of Student class
6print("Type of stu_obj is:", type(stu_obj))
بر اساس خروجی قطعه کد فوق، نوع داده شی، کلاسی است که از آن ساخته میشود. در مثال فوق، نوع داد شیstu_obj، کلاسStudentاست.
Type of stu_obj is: <class '__main__.Student'>
هر ماهیتی نظیر ساختار دادهها، کلاس، متغیرها و سایر موارد در زبان پایتون، به عنوان شی محسوب میشوند. بدینترتیب، کلاسها نیز خودشان به عنوان شیئی از یک کلاس دیگر هستند که به آن کلاس، «فرا کلاس | متا کلاس» (Metaclass) گفته میشود. در زبان پایتون، فرا کلاس، کلاسtypeاست که تمامی کلاسهای پایتون از این کلاس ساخته میشوند. در قطعه کد زیر، از دستورtype()به منظور تعیین نوع کلاسStudentاستفاده شده است:
1class Student:
2 pass
3
4# Print type of Student class
5print("Type of Student class is:", type(Student))
همانطور که در خروجی زیر ملاحظه میشود، نوع کلاسStudent، کلاسtypeاست و کلاسStudentبه عنوان شیئی از کلاسtypeمحسوب میشود.
Type of Student class is: <class 'type'>
نوع تمامی کلاسهای توکار زبان پایتون نیز از نوع کلاسtypeهستند. در ادامه، مثالی از خروجی نوع کلاسهای توکار پایتون ملاحظه میشود:
1 for t in int, float, dict, list, tuple:
2 print(type(t))
خروجی قطعه کد فوق در زیر آمده است:
<class 'type'> <class 'type'> <class 'type'> <class 'type'> <class 'type'>
برای معین کردن نوع کلاسtypeنیز، میتوان از قطعه کد زیر استفاده کرد:
1print(type(type))
خروجی قطعه کد فوق در ادامه ملاحظه میشود:
<class 'type'>
بدینترتیب، میتوان نتیجهگیریهای فوق را به شکل زیر خلاصهسازی کرد:
- هر ماهیتی در زبان پایتون به عنوان شی تلقی میشود.
- شی، نمونهای از کلاس است.
- کلاس در پایتون به عنوان شی محسوب میشود.
- شی کلاس، نمونهای از فرا کلاسtypeاست.
- کلاسtypeنیز شیئی از کلاس خودش است.
- کلاسtypeفرا کلاس تمام کلاسهای پایتون است. به عبارتی، تمامی کلاسهای پایتون از فرا کلاس ساخته میشوند.
فرا کلاس مشخص میکند که کلاسهای ساخته شده از آن، چه رفتاری داشته باشند. به عنوان مثال، میتوان در فرا کلاس قطعه کدی نوشت که بر اساس آن، هر کلاس فرزندی که از آن ساخته میشود، فقط دارای یک شی باشد. اعمال چنین محدودیتی برای دسترسی به پایگاه داده یا اطلاعات حساس حائز اهمیت است و به منظور کنترل دسترسی و بررسی سطح امنیت، میتوان ساخت اشیای کلاسهای فرزند را محدود به یک شی کرد.
ساخت فرا کلاس در زبان برنامه نویسی پایتون
در زبان برنامه نویسی پایتون با استفاده از کلمه کلیدیmetaclassدر قسمت اعلان کلاس، میتوان فرا کلاسی برای آن کلاس ایجاد کرد. در مثال زیر، نحوه تعریف متا کلاس با نامMyMetaملاحظه میشود. به منظور تعریف فرا کلاس، باید در قسمت اعلان کلاس، از کلمهtypeاستفاده کرد تا این متا کلاس از کلاسtypeساخته شود. کلاسMyClassنیز کلاسی است که از فرا کلاسMyMetaساخته شده است که کلاسMySubclassاز آن ارثبری میکند.
1class MyMeta(type):
2 pass
3
4class MyClass(metaclass=MyMeta):
5 pass
6
7class MySubclass(MyClass):
8 pass
9
10print(type(MyMeta))
11print(type(MyClass))
12print(type(MySubclass))
خروجی قطعه کد فوق، در ادامه ملاحظه میشود:
<class 'type'>
<class '__main__.MyMeta'>
<class '__main__.MyMeta'>
به منظور ساخت فرا کلاسی که از کلاسtypeساخته میشود، میتوان سه متد فهرست شده در زیر را نیز درون فرا کلاس بازنویسی کرد:
- متد__new__: این متد، پیش از اجرا شدن متد__init__فراخوانده میشود و شی کلاس را میسازد و سپس آن را بازمیگرداند. میتوان نحوه ساخت شی را با استفاده از این متد تغییر داد.
- متد__init__: میتوان از این متد به منظور مقداردهی اولیه ویژگیهای کلاس با استفاده از پارامترهای شی ساخته شده استفاده کرد.
- متد__call__: دستورات این متد زمانی اجرا میشوند که کلاس فراخوانی شود.
جمعبندی
کلاس و شی یکی از پرکاربردترین ماهیتهای برنامه نویسی هستند که بسیاری از برنامه نویسان در پروژههای خود از آنها استفاده میکنند. قابلیتهای این دو جزء برنامه نویسی باعث شده است تا در مفاهیم شیگرایی نیز از آنها استفاده شود. پایتون به عنوان یکی از زبانهای برنامه نویسی شیگرا، از کلاس به منظور پیادهسازی اصول شیگرایی استفاده میکند. در مطلب حاضر، سعی بر این بود تا به ارائه مفهوم کاملی از کلاس، اجزا و مفاهیم مرتبط با آن و نحوه ساخت و استفاده از آن در زبان برنامه نویسی پایتون پرداخته و با ذکر مثالهای کاربردی، نحوه پیادهسازی اصول شیگرایی در پایتون با استفاده از کلاس ارائه شود.
در توضیحات بخش «ویژگی __doc__ شی در پایتون» 2 مرتبه از عبارت ac.__doc__ استفاده شده است که باید بخش ac. آن حذف شود و فقط __doc__ بماند.
با سلام و احترام؛
سپاس از دقت نظر شما، این مورد اصلاح شد.
با تشکر از همراهی شما با مجله فرادرس
بسیار جامع، سپاس از زحمات شما بابت تنظیم این مطالب ❤️
بی نظیر
سلام،در قسمت کپسوله سازی مثال دوم یک ایرادی وجود داره.اونم اینکه اولا از کلاس هیچ نمونه ای ساخته نشده ولی روی نمونه jack عملیات اجرا شده
دوما به به متغیر ها و متد های private همینجوری نمیتونیم دسترسی داشته باشیم چون پایتون اسم اون ها رو تبدیل کرده (name mangling) و باید از اسم تبدیل شده برای فراخوانی متد private استفاده کنیم.
با سلام و احترام؛
صمیمانه از همراهی شما با مجله فرادرس و ارائه بازخورد سپاسگزاریم.
مورد اولی که اشاره کردید، اصلاح شد.
درباره قسمت دوم صحبتتون، در ابتدای قسمت کپسولهسازی به این نکته اشاره کردیم:
در برنامه نویسی، مستقیماً نمیتوان به متدهای خصوصی از خارج کلاس یا از طریق کلاسهای فرزند دسترسی داشت. به منظور تعریف متدهای خصوصی، پیش از نام متد، از علامت (_) در پایتون استفاده میشود. البته باید خاطرنشان کرد که پایتون، مانع استفاده از متد خصوصی خارج از کلاس نمیشود. به عبارتی، چنانچه از این متدها در خارج از کلاس، استفاده شوند، خطای کامپایلر رخ نمیدهد و تعریف متدهای خصوصی در پایتون فقط به سایر برنامه نویسان نشان میدهد که این متدها برای داخل کلاس استفاده میشوند. به بیان دیگر، استفاده از علامت (_) قراردادی برای تعیین نام متدهای خصوصی در میان برنامه نویسان است.
مورد name mangling درباره متغیرها و متدهایی هستند که با double underscore شروع میشوند. در پایتون به این متدها و متغیرها هم میشه از بیرون کلاس با استفاده از ساختار زیر دسترسی داشت:
object._ClassName__MethodName
برای شما آرزوی سلامتی و موفقیت داریم.