آموزش self در پایتون

امیرحسین بیگدلو 5 ماه قبل

 

 #  متغیر self در پایتون چیست؟

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

 

اگر دوست دارید همین مبحث را به شکل ویدیویی ببینید، میتوانید ویدیو توضیح method در پایتون را مشاهده کنید.

 

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

 

به مثال زیر دقت کنید:

class Person:
	def hello(self):
		print('Hello user...')

 

در مثال بالا، یک کلاس به نام Person و در داخل این کلاس یک متد به نام hello داریم که یک جمله را چاپ میکند. اگر دقت کنید، میبینید که اولین آرگومانی که متد hello گرفته کلمه self است. درست است که از کلمه self استفاده نکرده‌ایم، با این حال باید آن را داشته باشیم.

 

متغیر self یک کلمه کلیدی نیست و اگر بخواهید میتوانید نام دیگری را به آن بدهید. اما برای هماهنگ بودن کدهای نوشته با یکدیگر پیشنهاد میشود که نام اولین آرگومان هر متد را فقط self قرار دهید.

 

بیایید مثال دیگری بزنیم:

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

	def hello(self):
		print(f'Hello {self.name}...')

a = Person('amir')
a.hello()

# Hello amir

 

توضیح کد بالا:

 

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

 

2. متد hello فقط یک آرگومان دارد. با استفاده از متغیر self در این متد میتوان به اطلاعات هر آبجکت دسترسی داشت. در این مثال کلمه self در خود آبجکت a را دارد. پس میتوان برای دسترسی به name از آن استفاده کرد.

 

3. برای دسترسی به هر دیتایی از آبجکت، فقط کافیست از عملگر نقطه استفاده کنیم.

 

 

 #  آیا میتوان متغیر self را مشخص نکرد؟

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

 

به مثال زیر دقت کنید:

class Person:
	def hello():
		print(f'Hello User...')

a = Person()

 

در متد hello کلمه self را مشخص نکرده‌ایم اما بعد از اجرای برنامه با خطایی روبرو نمیشویم. چرا؟ چون هنوز متد hello را فراخوانی نکرده‌ایم. اگر متد hello را فراخوانی کنید، با خطا مواجه خواهید شد:

>>> a.hello()

Traceback (most recent call last):
  File "/home/amir/Desktop/python/four.py", line 7, in <module>
    a.hello()
TypeError: hello() takes 0 positional arguments but 1 was given

 

اما پیغام خطایی که پایتون نشان میدهد بسیار جالب است. این پیغام میگوید که متد hello انتظار هیچ آرگومانی را نداشت اما 1 آرگومان به آن ارسال شد در حالی که در کد ()a.hello ما به آن هیچ آرگومانی ارسال نکردیم.

 

دلیل این پیغام عجیب اینست که زمانی که متدی را فراخوانی میکنید، خود آبجکت به عنوان اولین آرگومان به آن متد ارسال میشود. پس زمانی که ()a.hello را صدا میزنید، آبجکت a به عنوان آرگومان به متد hello ارسال میشود. از آنجایی که کلمه self را از لیست آرگومان‌های متد حذف کرده‌اید، پایتون همچین پیغام خطایی را نشان میدهد.

 

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

>>> Person.hello()
Hello User...

 

 

 #  چرا متغیر self را حذف نمی کنند؟

ممکن است برایتان سوال باشد که چرا مانند زبان جاوا تعریف متغیر self را اتوماتیک نمی کنند تا مجبور نشویم هر دفعه آن را بنویسیم. بسیاری از برنامه نویسان این پیشنهاد را به توسعه دهندگان هسته اصلی پایتون دادند اما Guido van Rossum با آنها مخالفت کرد. میتوانید دلایل Guido van Rossum را در این لینک و این لینک ببینید.

مطالب مشابه



مونگارد