পাইথনে মিউটেবল এবং ইমিউটেবল

পাইথনে মিউটেবল এবং ইমিউটেবল

এই প্রবন্ধে পাইথনে মিউটেবল এবং ইমিউটেবল বিষয়ে ব্যাখ্যা করা হয়েছে।

YouTube Video

পাইথনে মিউটেবল এবং ইমিউটেবল

“মিউটেবল” এবং “ইমিউটেবল” দ্বারা একটি অবজেক্টের মিউটেবিলিটি বোঝানো হয়। এটি বোঝা অপ্রত্যাশিত বাগ এড়াতে এবং দক্ষ মেমোরি ব্যবস্থাপনা করতে সাহায্য করে।

মিউটেবল কী?

মিউটেবল অবজেক্টের ভেতরের অবস্থা তৈরি হওয়ার পর পরিবর্তন করা যায়

প্রধান মিউটেবল ডেটা টাইপ

  • list
  • dict
  • set
  • ইউজার-ডিফাইন্ড ক্লাস (যদি তাদের অ্যাট্রিবিউট পরিবর্তন করা যায়)

উদাহরণ: একটি তালিকা সংশোধন করা

1numbers = [1, 2, 3]
2numbers[0] = 100
3print(numbers)  # [100, 2, 3]

একটি তালিকা একটি মিউটেবল অবজেক্ট এবং এর উপাদানগুলো স্বাধীনভাবে পরিবর্তন করা যেতে পারে।

ইমিউটেবল কী?

ইমিউটেবল অবজেক্ট একবার তৈরি হয়ে গেলে পরিবর্তন করা যায় না।। এগুলিকে পরিবর্তন করার চেষ্টা করলে একটি নতুন অবজেক্ট তৈরি হয়।

প্রধান ইমিউটেবল ডেটা টাইপ

  • int
  • float
  • str
  • tuple
  • bool
  • frozenset

উদাহরণ: একটি স্ট্রিং সংশোধন করা

1text = "hello"
2# text[0] = "H"  # TypeError: 'str' object does not support item assignment
3
4text = "H" + text[1:]  # Creates a new string
5print(text)  # "Hello"

স্ট্রিংস ইমিউটেবল, তাই এগুলোকে আংশিকভাবে পরিবর্তন করা যায় না।

মিউটেবল এবং ইমিউটেবলের তুলনা

 1# Mutable example
 2a = [1, 2, 3]
 3b = a
 4b[0] = 100
 5print(a)  # [100, 2, 3] -> a is also changed
 6
 7# Immutable example
 8x = 10
 9y = x
10y = 20
11print(x)  # 10 -> x is unchanged

এই উদাহরণ থেকে আপনি দেখতে পাচ্ছেন, মিউটেবল অবজেক্টগুলো রেফারেন্স দ্বারা শেয়ার করা হয়, তাই তারা অন্যান্য ভেরিয়েবলকে প্রভাবিত করতে পারে। অন্যদিকে, অপরিবর্তনীয় অবজেক্টগুলি পুনরায় অ্যাসাইনমেন্টে নতুন ইনস্ট্যান্স তৈরি করে এবং মূল মানটি অপরিবর্তিত থাকে

id() ব্যবহার করে অভ্যন্তরীণ আচরণ পরিদর্শন করা হচ্ছে

পাইথনে, আপনি একটি অবজেক্টের আইডি পরীক্ষা করতে id() ফাংশন ব্যবহার করতে পারেন। অবজেক্টের আইডি একটি মেমরি ঠিকানার সাথে সাদৃশ্যপূর্ণ।

 1# Immutable int behavior
 2a = 10
 3print(id(a))  # e.g., 140715920176592
 4a += 1
 5print(id(a))  # e.g., 140715920176624 -> ID has changed
 6
 7# Mutable list behavior
 8b = [1, 2, 3]
 9print(id(b))  # e.g., 2819127951552
10b.append(4)
11print(id(b))  # Same ID -> only the content has changed

যেমনটি দেখানো হয়েছে, অপরিবর্তনীয় টাইপগুলির জন্য একটি নতুন অবজেক্ট তৈরি করা হয়, যেখানে পরিবর্তনীয় টাইপগুলি পরিবর্তিত স্থানেই সম্পাদিত হয়

ফাংশন এবং পরিবর্তনযোগ্য ও অপরিবর্তনীয় অবজেক্টগুলির সাথে সতর্কতা

যখন একটি পরিবর্তনযোগ্য অবজেক্ট ফাংশনে পাস করা হয়, মূল ডেটা পরিবর্তিত হতে পারে

উদাহরণ: একটি ফাংশন যা একটি তালিকা পরিবর্তন করে

1def modify_list(lst):
2    lst.append(100)
3
4my_list = [1, 2, 3]
5modify_list(my_list)
6print(my_list)  # [1, 2, 3, 100]

উদাহরণ: একটি ফাংশন যা একটি সংখ্যা পরিবর্তন করে

অন্যদিকে, একটি অপরিবর্তনীয় অবজেক্ট পরিবর্তন করার চেষ্টা করলে একটি নতুন অবজেক্ট তৈরি হয়।

1def modify_number(n):
2    n += 10
3
4my_number = 5
5modify_number(my_number)
6print(my_number)  # 5 -> unchanged

আচরণিক বিবেচনা

ডিফল্ট আর্গুমেন্ট হিসাবে পরিবর্তনযোগ্য অবজেক্টের ব্যবহার এড়িয়ে চলুন

 1# Bad example
 2def add_item(item, container=[]):
 3    container.append(item)
 4    return container
 5
 6print(add_item(1))  # [1]
 7print(add_item(2))  # [1, 2] -> unintended behavior
 8
 9# Good example
10def add_item(item, container=None):
11    if container is None:
12        container = []
13    container.append(item)
14    return container
15
16print(add_item(1))  # [1]
17print(add_item(2))  # [2]

ডিফল্ট আর্গুমেন্টগুলি শুধুমাত্র একবার ফাংশন সংজ্ঞায়নকালে মূল্যায়ন করা হয়; পরিবর্তনযোগ্য অবজেক্ট ব্যবহার করলে এটি অপ্রত্যাশিত পার্শ্বপ্রতিক্রিয়ার কারণ হতে পারে।

  • প্রথম উদাহরণে, প্রতিবার add_item ফাংশনটি কল করলে একই লিস্ট অবজেক্ট ব্যবহৃত হয়। দ্বিতীয়বার add_item(2) কল করার সময়, পূর্বে যুক্ত করা 1 এখনো তালিকায় থাকে, ফলে ফলাফল হয় [1, 2]
  • উন্নত উদাহরণে, ডিফল্ট মান হিসেবে None ব্যবহৃত হয়েছে এবং যদি আর্গুমেন্টটি None হয়, তাহলে ফাংশনের ভিতরে একটি নতুন লিস্ট তৈরি করা হয়। এটি নিশ্চিত করে যে প্রতিবার ফাংশনটি কল হলে একটি নতুন তালিকা তৈরি হয়, ফলে পূর্ববর্তী ফলাফলগুলো পরবর্তী কলগুলোকে প্রভাবিত করে না।

ডিফল্ট আর্গুমেন্ট হিসেবে তালিকা বা ডিকশনারির মতো মিউটেবল অবজেক্ট ব্যবহার এড়িয়ে চলুন; তার পরিবর্তে None ব্যবহার করুন এবং ফাংশনের ভিতরে সেগুলো ইনিশিয়ালাইজ করুন। এটি পাইথনের একটি মৌলিক এবং গুরুত্বপূর্ণ সেরা অনুশীলন (best practice)।

সারসংক্ষেপ

পাইথনের ভেরিয়েবল এবং ডেটা টাইটপগুলিকে গভীরভাবে বুঝতে হলে পরিবর্তনযোগ্য এবং অপরিবর্তনীয় মধ্যে পার্থক্য বোঝা গুরুত্বপূর্ণ। এই বৈশিষ্ট্যগুলি বোঝা আপনাকে আপনার কোডে অপ্রত্যাশিত আচরণ এড়াতে এবং আরও বেশি দৃঢ় এবং পাঠযোগ্য প্রোগ্রাম লিখতে সাহায্য করে।

আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।

YouTube Video