مسیر شما: سبز دانش » برنامه نویسی » پایتون » آموزش متد init در پایتون: ساده با مثال و کد + ۴ نکته
وقتی در پایتون با کلاسها کار میکنیم، معمولاً لازم داریم یکسری بیانات اولیه برای آن مشخص کنیم. مثلاً اگر یک کلاس Person داشته باشیم، ممکن است بخواهیم در هنگام ایجاد شیء از آن، نام و سن آن را نیز تعریف کنیم. اینجاست که متد init در پایتون به کارمان میآید.
متد __init__() هنگام ساختهشدن یک شیء از کلاس بهصورت خودکار اجرا میشود و معمولاً از آن برای مقداردهی اولیه مشخصههای شیء استفاده میکنیم.
مثلاً وقتی مینویسیم:
class Person:
def __init__(self, name):
self.name = name
person_object = Person("Omid")هنگام اجرای Person("Omid") پایتون فرآیند ساخت شیء را انجام میدهد. سپس __init__ را برای مقداردهی اولیه آن اجرا میکند. اینطوری مقدار self.name برابر با "Omid" میشود. در این آموزش بهطور دقیقتر متوجه میشویم که این متد چیست، self در آن چه نقشی دارد و چه نکاتی را بهتر است در تعریف این متد رعایت کنیم.
فهرست محتوای آموزش
قبل از هر چیزی، بهتر است یک مرور کوتاه روی کلاس و شیء داشته باشیم. کلاس (Class) را میتوانیم مثل یک الگو یا قالب در نظر بگیریم. شیء (Object / نمونه یا instance) نیز نمونهای از آن قالب است که ساخته شده است.
مثلاً اگر Person یک کلاس باشد، میتوانیم چندین شخص (شیء) مختلف از آن بسازیم:
person1 = Person("Sara")
person2 = Person("Omid")اگر با مفاهیم کلاس و شیء آشنا نیستید، پیشنهاد میکنم حتماً آموزش ویدیویی و متنی کلاس در پایتون را ببینید.
کلاس زیر را در نظر بگیرید:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
print("شخص بهروز ساخته شد!")اگر از این کلاس یک شیء بسازیم، در خروجی پیام «شخص تازه ساخته شد!» را میبینیم و شیء نیز ساخته میشود:
person = Person("Sara", 25) # شخص بهروز ساخته شد!حال اگر مقادیر name و age این شیء را تحلیل کنیم، میبینیم که دقیقاً همان مقادیری را گرفتهاند که هنگام ساخت شیء بهعنوان آرگومان تعریف کرده بودیم:
print(person.name) # Sara
print(person.age) # 25دقیقاً چه اتفاقی میافتد؟
با اجرای دستور Person("Sara", 25) یک شیء از کلاس Person ایجاد میشود و سپس پایتون متد __init__ را برای آن فراخوانی میکند. علاوه بر این مقادیر "Sara" و 25 بهعنوان آرگومانها به این متد ارسال میشوند.
در بدنهٔ متد init این دو مقدار را در خصوصیتهای شیء (Propertyهایش) ذخیره میکنیم. واضح است که نام propertyها میتواند با نام آرگومانها متفاوت باشد. مثلاً داشته باشیم:
class Person:
def __init__(self, name_var, input_age):
self.name = name_var
self.age = input_age
print("شخص بهروز ساخته شد!")بنابراین کاربرد اصلی متد __init__ در پایتون این است که شیء را هنگام ساختهشدن مقداردهی اولیه کنیم.
همان مثال کلاس Person را در نظر بگیرید:
class Person:
def __init__(self, name, age):
self.name = name
self.age = ageمتد init مانند هر متد دیگری، سه بخش کلی دارد:
نام این متد __init__ است. این یک نام از پیشتعریفشده است و نباید آن را تغییر دهیم. اگر آن را تغییر دهیم، دیگر متدی که برای مقداردهی باشد نداریم.
به متدهایی که با دو تا underline (_) احاطه شدهاند، اصطلاحاً Dunder Method گفته میشود. برای آشنایی بیشتر با این متدها و انواع آن میتوانید آموزش متد جادویی (ویژه) در پایتون را ببینید.
اولین پارامتر ورودی این متد، self است و پس از آن میتواند صفر یا چند پارامتر دیگر داشته باشد. در مثال بالا، دو پارامتر دیگر داریم که با self میشود سه مورد.
اما self در پایتون چیست؟
کلمه کلیدی self به شیء فعلی اشاره میکند. با کمک آن میتوانیم مشخص کنیم که خصوصیتای که در حال مقداردهی آن هستیم، متعلق به همین شیء است.
قطعه کد زیر را در نظر بگیرید:
class Person:
def __init__(self, name):
self.name = name
p1 = Person("Sara")
p2 = Person("Omid")در p1 عبارت self.name به یک مشخصه (property) در شیء p1 اشاره میکند که نامش name است. علاوه بر این در p2، عبارت self.name به name درون p2 اشاره میکند.
نکته مهم: کلمه self یک نام رزروشده نیست؛ این نام یک قرارداد رایج در پایتون است. ما برنامهنویسها تقریباً همیشه از همین نام استفاده میکنیم تا کدهایمان برای دیگران واضح باشد. در غیر اینصورت مجبور نیستیم و میتوانیم بهجای self مثلاً this تعریف کنیم!
__init__ یک متد است. از جلسات دوره آموزش پایتون میدانیم که متدها در کلاس همان ساختار تابع (function) را دارند. بنابراین در بدنهٔ این متد میتوانیم تقریباً هر چیزی بنویسیم!
در مثال زیر یک کلاس محصول (Product) داریم که در بدنهٔ متد init آن بهای که بهعنوان ورودی داده شده را با صفر مقایسه میکنیم؛ اگر عدد مثبت بود، همان را برای نرخ در نظر میگیریم؛ وگرنه (اگر صفر یا منفی بود) بها محصول را صفر میگذاریم. چون نرخ منفی برای محصول اشتباه است.
class Product:
def __init__(self, name, price):
self.name = name
if price > 0:
self.price = price
else:
self.price = 0میتوانیم در بدنه متد __init__ از ساختارهای شرط، حلقه و حتی فراخوانی یک تابع در پایتون استفاده کنیم.
تا اینجا با init در پایتون آشنا شدیم و فهمیدیم در کجاها و با چه هدفی استفاده میشود. در این بخش چهار نکته در کار با آن را ارزیابی میکنیم.
لازم نیست که حتماً در هر کلاس متد __init__ را تعریف کنیم. میتوانیم بدون هیچ مشکلی از کلاسی که این متد را ندارد نیز شیء بسازیم و با آن کار کنیم.
فقط هر زمان که نیاز داشتید هنگام ایجاد شیء، قابلیتهایی را مقداردهی اولیه کنید، این متد را تعریف کنید.
برای مثال، قطعه کد زیر دقیقاً صحیح است:
class Person:
def say_hello(self):
print("Hello!")
person = Person()
person.say_hello()همانطور که کمی قبلتر اشاره کردم، __init__() نیز مانند سایر متدهای یک کلاس میتواند صفر یا چند پارامتر داشته باشد. البته فراموش نکنید که پارامتر self همیشه در همه متدهای عادی وجود دارد.
متد init در کلاس زیر هیچ پارامتر ورودی ندارد:
class Person:
def __init__(self):
self.name = "Unknown"در کلاس زیر یک پارامتر اجباری دارد:
class Person:
def __init__(self, name):
self.name = nameدر مثال زیر یک پارامتر دارد که برایش مقدار پیشفرض در نظر گرفتهایم:
class Person:
def __init__(self, name="Guest"):
self.name = nameهر سه حالت صحیح هستند. ما متناسب با نیاز پروژه و کلاسی که تعریف میکنیم میتوانیم از هر حالتی استفاده کنیم.
یکی از اشتباههای رایج در تعریف متد init در پایتون این است که داخل بدنهٔ آن، مقداری را retu کنیم. قطعه کد زیر اشتباه است:
class Person:
def __init__(self, name):
self.name = name
return nameاین کد باعث ایجاد خطا میشود. (خطای TypeError) چون متد __init__ باید None برگرداند ولی در اینجا یک مقدار رشته در پایتون برگردانده است.
البته استفاده از retu خالی برای خروج زودهنگام از متد هیچ مشکلی ندارد و میتوانیم از آن استفاده کنیم. چون retu خالی عملاً مقدار None برمیگرداند.
در ارثبری (inheritance) کلاسها ممکن است کلاس فرزند علاوه بر مقداردهی خودش نیاز داشته باشد متد __init__ والد خود را نیز فراخوانی کند. در این حالت میتوانیم از تابع super() استفاده کنیم.
قطعه کد زیر را ببینید. متد init در کلاس Student ابتدا متد __init__() والد خود را فراخوانی کرده و سپس مقدار grade را درون خودش مقداردهی کرده است.
class Person:
def __init__(self, name):
self.name = name
class Student(Person):
def __init__(self, name, grade):
super().__init__(name)
self.grade = gradeاگر با ارثبری بهطور جامع آشنا نیستید، پیشنهاد میکنم جلسه آموزش ارثبری در پایتون را ببینید.
در اکثر آموزشهای برنامهنویسی پایتون، متد __init__() را متد سازنده (Constructor) مینامند؛ اما از نظر فنی این تعبیر دقیق نیست. در حقیقت متد __new__() مسئول ایجاد شیء و سازندهٔ کلاس است. متد __init__ پس از ایجاد شیء برای مقداردهی اولیه و آمادهسازی آن اجرا میشود. (منبع در مستندات) ما برای استفاده معمول از کلاسها تقریباً همیشه با __init__ سروکار داریم و معمولاً نیازی به بازنویسی __new__ نداریم.
پس اگر جایی شنیدید «متد سازنده در پایتون» معمولاً منظور همان __init__ است؛ این یک اصطلاح رایج است اما بدانید که از نظر فنی اشتباه است.
در این آموزش فهمیدیم که __init__() یکی از متدهای ویژه پایتون است که پس از ایجاد شیء، برای مقداردهی اولیه اجرا میشود. مثلاً میتوانیم گزارشهای مانند نام، سن، ارزش محصول، ایمیل یا هر دادهٔ اولیه دیگری را هنگام ایجاد شیء مقداردهی کنیم.
در یک کلاس، برای یک نام متد مشخص مثل __init__() فقط یک تعریف نهایی داریم. اگر __init__ را دو بار در یک کلاس تعریف کنیم، تعریف دوم جای تعریف اول را میگیرد. بنابراین نمیتوانیم مثل بعضی زبانهای برنامهنویسی دیگر، چند __init__ با پارامترهای متفاوت داشته باشیم. برای این کار معمولاً از پارامترهای پیشفرض یا منطق شرطی درون بدنه استفاده میکنیم.
برای جمعبندی، به مثال زیر توجه کنید:
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
product = Product("Laptop", 2000)وقتی Product("Laptop", 2000) را مینویسیم، شیء product از کلاس Product ایجاد میشود و دو مشخصه name و price در آن مقداردهی اولیه میشوند. (در کد بهاش را به دلار نوشتم ؛ متأسفانه به تومان باید صفرهای خیلی زیادی میگذاشتم!)
امیدوارم از این آموزش استفاده کرده باشید. اگر سؤال یا چالشی در استفاده از متد init در پایتون دارید، در بخش دیدگاهها مطرح کنید.
این آموزش برای همیشه بدون هزینهه! میتونید با اشتراکگذاری لینک این صفحه از ما حمایت کنید یا با سفارش یه فنجون نوشیدنی بهمون انرژی بدید!
برچسب:
نویسنده: استخدام کار