آموزش پایتون - هویت اشیاء
در این سری از مقالات قصد دارم نکات کلیدی که در زبان پایتون وجود دارد را ارائه کنم. در این مجموعه تلاش شده اطلاعات مختصر و کوتاه باشند و بر مهمترین نکات مورد نیاز تمرکز شود.
بعد از گذراندن این دوره شما قادر خواهید بود که از هر کتابخانه پایتون استفاده کنید و بستههای پایتونی که خودتان نوشتهاید را اجرا کنید.
عناوین دوره:
- مقدمه
- نصب و راهاندازی
- متغیرها و انواع داده
- عبارتهای کنترلی
- توابع و ماژولها
- هویت اشیاء
- مدیریت خطا
- برنامهنویسی شیگرا
- بستهبندی و انتشار کد
در این مقاله یکی از مهمترین مفاهیم در پایتون بنام هویت اشیاء (Object Identity) را توضیح میدهیم. همانطور که در بخش متغیرها و انواع دادهها نیز اشاره شد هر چیزی در پایتون یک شی محسوب میشود.
هر زمان که ما یک شی را در پایتون به صورت یک متغیر، تابع، و غیره ایجاد میکنیم، مفسر پایتون (CPython) یک آدرس در حافظه اختصاص میدهد که به صورت منحصر به فرد آن شی را مشخص میکند. تابع id در پایتون کد شناسایی مربوط به آدرس اختصاصی هر شی را برمیگرداند.
اجازه دهید با یک مثال مفهوم را بصورت جزئیتر توضیح دهیم:


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


همانطور که ملاحظه میکنید پایتون آدرس جدیدی در حافظه برای متغیرهای 5 و 6 بوجود نمیآورد و آنها را با همان متغیرهای 1 و 4 آدرسدهی میکند.
حال فرض کنید بخواهیم یک متغیر را مجددا مقدار دهی کنیم:


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


عجیب نیست؟؟؟ کد شناسایی یکسان حتی پس از تغییر!!
دقت کنید همانطور که در بخش دادهها نیز به آن اشاره شد برخی از دادهها در پایتون تغییرپذیر (Mutable) و برخی دیگر تغییرناپذیرند (Immutable).


این مفهوم مهم را در آدرسدهی حافظه مفسر پایتون میتوان بوضوح درک کرد. همانطور که مشاهده شد متغیر 1 که یک داده تغییرناپذیر از نوع عدد است پس از مقداردهی مجدد، در آدرس دیگری از حافظه قرار گرفت، حال آنکه متغیر 6 که یک داده تغییرپذیر از نوع لیست است پس از تغییر با همان آدرس قبلی در حافظه شناسایی میشود.
اجازه دهید تا با یک تابع کمی بیشتر در مورد متغیر و آدرس دهی حافظه آن توسط CPython صحبت کنیم. در مثال زیر ما یک متغیر از نوع تغییرپذیر را مقداردهی میکنیم سپس متغیر به تابع وارد شده و درون تابع بروزرسانی میشود.


همانطور که مشاهده میکنید متغیر درون تابع به همان آدرس متغیر 6 اشاره دارد. این نشان میدهد که تابع همان شی را بروز کرده است.
در مثال زیر متغیر 6 درون تابع مجددا مقدار دهی میشود:


این نشان میدهد که متغیر به محض مقداردهی درون تابع از شناسه متفاوتی برخوردار میشود و بدون توجه به نوع داده (تغییرپذیر یا تغییرناپذیر) با خروج از محل تابع، دیگر به آن دسترسی نداریم.
پایتون همیشه یک آدرس حافظه جدید برای همه متغیرهای جدید ایجاد نمیکند. بصورت مشخصتر متغیرهای تغییرپذیر list, set و dictionary در پایتون با بروزرسانی حتی درون یک تابع نیز آدرس جدیدی در حافظه ایجاد نمیکنند.
حال حدس میزنید اگر ما به دو متغیر متفاوت یک مقدار یکسان مانند "a" نسبت دهیم، آیا دو آدرس حافظه برای شما ایجاد خواهد کرد؟


همانطور که مشاهده میکنید هر دو متغیر آدرس یکسانی در حافظه دارند.
حال اگر به دو متغیر یک رشته طولانی نسبت دهیم چه اتفاقی خواهد افتاد؟


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