آشنایی با نحوه ی نمونه سازی آبجکت ها از روی یک کلاس و دسترسی به اتریبیوت های آن در زبان پایتون


در آموزش قبل با مفهوم کلاس در زبان Python آشنا شدیم و دانستیم که تعریف یک کلاس مانند یک الگوی مشترک است که می توان از روی آن ها آبجکت های مختلف را نمونه سازی کرد. بر اساس دانسته های خود، کلاسی ساده تحت عنوان ShapeClass.py به شکل زیر پیاده سازی می کنیم:

class Shape:
    size

همان طور که در کد فوق ملاحظه می شود، ابتدا کلیدواژه ی class را نوشته و نامی دلخواه همچون Shape به معنی «شکل» برای کلاس خود در نظر می گیریم و یک علامت : هم پس از آن قرار می دهیم. یک متغیر هم تحت عنوان size به معنی «اندازه» با در نظر گرفتن تورفتگی ایجاد کرده ایم که دارای هیچ نوع مقدار اولیه یی نیست. حال می توانیم از روی کلاس Shape به صورت زیر نمونه سازی کنیم:

my_rect = Shape()
my_circle = Shape()

در حقیقت زمانی که ما دستور ()Shape را فراخوانی می کنیم، متد () __new__ برای ساخت آبجکت جدید و ()__init__ برای مقداردهی اولیه به آن فراخوانی می شوند؛ بنابراین اگر بخواهیم در زمان تعریف یک شیئ مقادیر اولیه ای را به اتریبیوت های آن آبجکت منتسب کنیم، باید از متد ()__init__ استفاده کنیم. برای مثال کلاس Shape را به صورت زیر بازنویسی می کنیم:

class Shape:
    size = 2
     def __init__(self, name, color):
      self.name = name
      self.color = color

اولین آرگومانی که به این متد و دیگر متدهای کلاس داده می شود self است که نماینده ی نمونه ی ایجاد شده از روی کلاس است، و پس از آن آرگومان هایی به متد ()__init__ داده می شود که می خواهیم در زمان ایجاد هر آبجکت جدید از این کلاس آن ها را مقداردهی کنیم. برای مثال، در کد نمونه آرگومان های name و color به این متد داده شده است و در بدنه ی متد ()__init__ دستور self.name = name مشخص می کند که اتریبیوت name برای آبجکت نمونه سازی شده از این کلاس باید به مقدار آرگومان name منتسب شود و دستور self.color = color نیز اتریبیوت color را برای آبجکت نمونه سازی شده به مقدار آرگومان color منتسب می کند. حال اگر بخواهیم آبجکت های جدیدی را از این کلاس ایجاد کنیم به صورت زیر عمل می کنیم:

shape1 = Shape('Circle','Yellow')
shape2 = Shape('Square','Green')

دو آبجکت shape1 و shape2 با دستورات بالا ایجاد و اتریبیوت های name و color برای آن ها مقدار دهی می شوند. حال می توانیم مانند آن چه در آموزش قبل توضیح داده شد، با استفاده از عملگر . به مقدار اتریبیوت های این دو شیء دسترسی پیدا کنیم:

>>> print(shape1.name)
Circle
>>> print(shape2.color)
Green

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

shape1.color = 'blue'
shape1.radius = 20
del shape1.name)

در دستور اول مقدار جدیدی را به اتریبیوت color متعلق به آبجکت shape1 منتسب می کنیم. در دستور دوم اتریبیوت جدیدی را با شناسه ی radius و مقدار 20 به آبجکت shape1 منتسب می کنیم و در نهایت در دستور سوم با استفاده از کیورد del و سپس فراخوانی اتربیوت name متعلق به آبجکت shape1 این اتریبیوت را از آبجکت مد نظر حذف می کنیم. حال خروجی کدهای زیر را می بینیم:

>>> print(shape1.color)
blue
>>> print(shape1.radius)
20
>>> print(shape1.name)
Traceback (most recent call last):
  File "C:/SokanAcademy/MyClass.py", line 19, in 
    print(shape1.name)
AttributeError: 'Shape' object has no attribute 'name'

همان طور که می بینید در دو دستور اول، آخرین مقادیر منتسب شده به اتریبیوت های آبجکت shape1 در خروجی چاپ شده اند اما خروجی دستور پرینت سوم خطایی است که اعلام می کند آبجکت shape1 اتریبیوتی با شناسه ی name ندارد و این خطا به درستی نمایش داده شده است چرا که ما پیش از این با دستور del این اتریبیوت را از آبجکت مورد نظر حذف کرده بودیم. علاوه بر روش اشاره شده، می توانیم از فانکشن های زیر نیز برای مدیریت اتریبیوت های یک آبجکت استفاده کنیم:

کاربرد فانکشن
برای دسترسی به اتریبیوت های یک آبجکت getattr(obj, name[default])
برای بررسی این که یک آبجکت اتریبیوت خاصی را دارد یا خیر hasattr(obj, name)
برای مقداردهی به یک اتریبیوت متعلق به آبجکتی خاص. اگر این اتریبیوت موجود باشد مقدار جدیدی می گیرد و در غیر اینصورت اتریبیوت جدیدی با مقدار داده شده به آبجکت منتسب می شود. setattr(obj, name, value)
برای حذف یک اتریبیوت از یک آبجکت delattr(obj, name)

کاربرد این فانکشن ها را بر روی آبجکت های بالا ببنید:

>>>print(hasattr(shape2, 'radius')) # Returns true if 'radius' attribute exists
False
>>>print(getattr(shape1, 'radius')) # Returns value of 'radius' attribute
20 
>>>setattr(shape2, 'radius', 8) # Set attribute 'radius' at 8
>>>delattr(shape1, 'color') # Delete attribute 'color'

خروجی دستور اول False است، چون هرگز اتریبیوت radius را به آبجکت shape2 منتسب نکردیم. خروجی دستور دوم نیز مقدار منتسب شده به اتریبیوت radius متعلق به آبجکت shape1 است. دستور سوم اتریبیوت radius را با مقدار 8 به آبجکت shape2 منتسب می کند و دستور آخر هم اتریبیوت color را از آبجکت shape1 حذف می کند.

دانلود فایل‌های تمرین
لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
sara
sara
۱۳۹۵/۱۱/۱۸
چراگزینه haveattr به عنوان جواب درست توی آزمون درنظر گرفته شده ؟:)
محمدهادی
محمدهادی
۱۳۹۵/۰۸/۳۰
متد ()__init__ رو مگه خودمان تعریف نکردیم؟ یا از پیش تعریف شدس. چجوریه؟!
saeedx4
saeedx4
۱۳۹۵/۱۲/۲۳
متد ()__init__ از پیش تعریف شده است به متدهای که دو تا زیر خط اول آخر اسمشون دارن متدهای مجیک (جادویی) گفته میشه. ما بدنه متد __init__ رو می نویسیم. اجباری نداریم که __init__ رو در برنامه تعریف کنیم می تونیم کلاسی داشته باشیم که __init__ رو تعریف نکرده باشه.

در پاسخ به

فردی
فردی
۱۳۹۵/۰۷/۲۵
با سلام
del shape1.name و delattr(shape1, name) چه فرقی دارند؟ یکی هستند؟
saeedx4
saeedx4
۱۳۹۵/۱۲/۲۳
نه یکی نیستند del کلمه کلیدی است که برای پاک کردن هر شی مورد مورد استفاده قرار می گیره مثلا میشه از del استفاده کرد و یک عنصر از لیستی رو پاک کرد. در طرفه دیگه delattr برای پاک کردن اتربیوت یک شی مورد استفاده قرار میگیره. سرعت پاک del هم بیشتر از delattr است.

در پاسخ به

shayan izi
shayan izi
۱۳۹۵/۰۶/۰۸
لدفا ادامه بدین !!‌
Alireza
Alireza
۱۳۹۵/۰۵/۳۱
با سلام و خسته نباشید خدمت مولفین این سایت مفید
با تشکر از زحمات شما که با داشتن مشغله های زیاد وقت میگذارید و این مطالب رو محیا میکنید.
آموزش ها و نحوه نگارش متن ها فوق العاده است و به نظر من باید خیلی از مولفین از این نوع نگارش ها الگو برداری کنند.
من قبل از اینکه آموزش پایتون رو با سایت شما شروع کنم اصلا فکر نمیکردم بتونم مفاهیم اولیه رو به این سرعت یادبگیرم.
واقعا خسته نباشید...
با تشکر