خانه / آموزش‌ها / تفاوت Mutable و Immutable در پایتون

تفاوت Mutable و Immutable در پایتون

🐍 HomeOfPython
|
📅 1404/10/22

سطح مقدماتی (Beginner Level)

یکی از مفاهیم پایه‌ای و بسیار مهم در پایتون، درک تفاوت بین اشیاء تغییرپذیر (Mutable) و تغییرناپذیر (Immutable) است. اینکه بدانید کدام داده‌ها را می‌توان تغییر داد و کدام‌ها ثابت هستند، جلوی بسیاری از باگ‌های ناخواسته را می‌گیرد.

مفهوم تغییرپذیر (Mutable)

اشیاء Mutable اشیایی هستند که مقدار آن‌ها پس از ساخته شدن قابل تغییر است، بدون اینکه آدرس حافظه (ID) آن‌ها عوض شود. انواع داده رایج Mutable عبارتند از:

  • لیست‌ها (Lists)
  • دیکشنری‌ها (Dictionaries)
  • مجموعه‌ها (Sets)

مثال ۱: تغییر محتوای لیست

در این مثال می‌بینیم که با تغییر لیست، آدرس حافظه آن ثابت می‌ماند.

Python

مثال ۲: رفتار دیکشنری

دیکشنری‌ها نیز Mutable هستند و می‌توان کلیدها و مقادیر آن‌ها را تغییر داد.

Python

مفهوم تغییرناپذیر (Immutable)

اشیاء Immutable اشیایی هستند که پس از ساخته شدن نمی‌توانند تغییر کنند. اگر سعی کنید آن‌ها را تغییر دهید، پایتون یک شیء جدید در حافظه می‌سازد. انواع داده رایج Immutable عبارتند از:

  • اعداد (Integers, Floats, Booleans)
  • رشته‌ها (Strings)
  • تاپل‌ها (Tuples)

مثال ۳: تلاش برای تغییر رشته

رشته‌ها تغییرناپذیرند. هر عملیاتی که به نظر می‌رسد رشته را تغییر می‌دهد، در واقع یک رشته جدید برمی‌گرداند.

Python

مثال ۴: تغییر اعداد

حتی اعداد صحیح هم در پایتون Immutable هستند.

python
# Example 4: Integer reassignment (Static snippet)
x = 10
# با این کار، مقدار ۱۰ تغییر نمی‌کند، بلکه متغیر x به مکان جدیدی اشاره می‌کند که مقدار ۱۱ دارد
x = x + 1

سطح پیشرفته (Professional Level)

درک عمیق Mutability برای نوشتن کدهای بهینه و جلوگیری از باگ‌های پنهان، به‌ویژه در توابع و مدیریت حافظه، ضروری است.

دام آرگومان‌های پیش‌فرض (Mutable Default Arguments)

یکی از رایج‌ترین اشتباهات حرفه‌ای‌ها، استفاده از یک شیء Mutable (مثل لیست یا دیکشنری) به عنوان مقدار پیش‌فرض در توابع است. این شیء تنها یک بار در زمان تعریف تابع ساخته می‌شود و بین تمام فراخوانی‌ها مشترک است.

مثال ۵: باگ لیست مشترک

در اینجا انتظار داریم هر بار یک لیست خالی ایجاد شود، اما لیست قبلی حفظ می‌شود.

Python

مثال ۶: راه حل صحیح (استفاده از None)

روش استاندارد برای حل مشکل بالا، استفاده از None به عنوان مقدار پیش‌فرض است.

Python

تاپل‌های "تغییرپذیر"! (Immutable containing Mutable)

اگرچه تاپل‌ها Immutable هستند، اما اگر حاوی یک شیء Mutable (مثل لیست) باشند، محتویات آن شیء داخلی قابل تغییر است. این موضوع می‌تواند در هش کردن (Hashing) و استفاده از تاپل به عنوان کلید دیکشنری مشکل ایجاد کند.

مثال ۷: تغییر محتوای درون تاپل

Python

بهینه‌سازی حافظه و Interning

پایتون برای اشیاء کوچک Immutable (مثل اعداد صحیح کوچک و رشته‌های خاص)، از تکنیکی به نام Interning استفاده می‌کند تا حافظه را ذخیره کند. یعنی اگر دو متغیر مقدار یکسانی داشته باشند، ممکن است به یک آدرس حافظه اشاره کنند.

مثال ۸: بررسی هویت اشیاء (Is vs Equal)

Python

استفاده در کلیدهای دیکشنری

فقط اشیاء Hashable می‌توانند کلید دیکشنری باشند. تمام اشیاء Immutable لزوماً Hashable نیستند (مثل تاپلی که لیست دارد)، اما تمام اشیاء Mutable قطعاً Unhashable هستند.

python
# Example 9: Valid vs Invalid Dict Keys
valid_dict = {
    (1, 2): "Tuple Key",      # OK
    "key": "String Key",      # OK
    10: "Int Key"             # OK
}

# invalid_dict = {
#     [1, 2]: "List Key"      # TypeError: unhashable type: 'list'
# }