এই টিউটোরিয়ালে, আমরা পাইথন ক্লাস-এ প্রাইভেট ভেরিয়েবল সম্পর্কে জানব।
পাইথনে সরাসরি প্রাইভেট ভেরিয়েবল এর কোনো ধারণা নেই। তবে, অধিকাংশ পাইথন ডেভেলপার একটি নামকরণ কনভেনশন মেনে চলেন যাতে বোঝা যায় কোনো ভেরিয়েবল পাবলিক নয়, বরং প্রাইভেট।
একটি ভেরিয়েবল প্রাইভেট (যথার্থতে নয়) হিসেবে নির্দেশ করতে এর নামের শুরুতে ডাবল আন্ডারস্কোর ব্যবহার করতে হয়। উদাহরণস্বরূপ: __one, __two ইত্যাদি।
যে ভেরিয়েবলগুলির নাম ডাবল আন্ডারস্কোর দিয়ে শুরু হয়, সেগুলো আসলে প্রাইভেট নয়। আমরা এখনও সেগুলো অ্যাক্সেস করতে পারি। চলুন দেখি কিভাবে প্রাইভেট টাইপের ভেরিয়েবল তৈরি করা যায় এবং তারপর সেগুলো কিভাবে অ্যাক্সেস করা যায়।
উদাহরণ
# ক্লাস তৈরি
class Sample:
def __init__(self, nv, pv):
# সাধারণ ভেরিয়েবল
self.nv = nv
# প্রাইভেট ভেরিয়েবল (যথার্থতে নয়)
self.__pv = pv
# ক্লাসের ইনস্ট্যান্স তৈরি
sample = Sample('Normal variable', 'Private variable')
আমরা একটি ক্লাস এবং তার ইনস্ট্যান্স তৈরি করেছি। __init__ মেথডের ভিতরে দুটি ভেরিয়েবল আছে—একটি সাধারণ আরেকটি প্রাইভেট। এখন ভেরিয়েবল দুটো অ্যাক্সেস করার চেষ্টা করি এবং দেখি কী ঘটে।
উদাহরণ
# ক্লাস তৈরি
class Sample:
def __init__(self, nv, pv):
# সাধারণ ভেরিয়েবল
self.nv = nv
# প্রাইভেট ভেরিয়েবল (যথার্থতে নয়)
self.__pv = pv
# ক্লাসের ইনস্ট্যান্স তৈরি
sample = Sample('Normal variable', 'Private variable')
# nv অ্যাক্সেস
print(sample.nv)
# __pv অ্যাক্সেস করার চেষ্টা
print(sample.__pv)
আউটপুট
উপরোক্ত কোড রান করলে নিচের আউটপুট পাবেন:
Normal variable
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-13-bc324b2d20ef> in <module>
14
15 # accessing *__pv**
---> 16 print(sample.__pv)
AttributeError: 'Sample' object has no attribute '__pv'
প্রোগ্রাম nv ভেরিয়েবলটি কোনো ত্রুটি ছাড়া দেখিয়েছে। কিন্তু __pv ভেরিয়েবলটি অ্যাক্সেস করার সময় AttributeError পেলাম।
এই ত্রুটি কেন? কারণ __pv নামে কোনো অ্যাট্রিবিউট وجود নেই। তবে self.__pv = pv স্টেটমেন্ট __init__ মেথডে তো আছে? এই বিষয়ে আমরা শীঘ্রই আলোচনা করব। প্রথমে দেখি __pv ভেরিয়েবলটি কিভাবে অ্যাক্সেস করা যায়।
ডাবল আন্ডারস্কোর দিয়ে শুরু হওয়া যেকোনো ক্লাস ভেরিয়েবলকে _ClassName__variableName ফর্মে অ্যাক্সেস করা যায়। আমাদের উদাহরণে সেটি হবে _Sample__pv। এখন এই নামে অ্যাক্সেস করি।
উদাহরণ
# ক্লাস তৈরি
class Sample:
def __init__(self, nv, pv):
# সাধারণ ভেরিয়েবল
self.nv = nv
# প্রাইভেট ভেরিয়েবল (যথার্থতে নয়)
self.__pv = pv
# ক্লাসের ইনস্ট্যান্স তৈরি
sample = Sample('Normal variable', 'Private variable')
# nv অ্যাক্সেস
print(sample.nv)
# __pv অ্যাক্সেস _Sample__pv নামে
print(sample._Sample__pv)
আউটপুট
উপরোক্ত কোড রান করলে নিচের ফলাফল পাবেন:
Normal variable Private variable
__pv ভেরিয়েবলের নাম কেন পরিবর্তন হয়েছে?
পাইথনে নেম मैंگلিং (Name Mangling) নামে একটি ধারণা আছে। পাইথন ডাবল আন্ডারস্কোর দিয়ে শুরু হওয়া ভেরিয়েবলদের নাম পরিবর্তন করে দেয়। তাই ডাবল আন্ডারস্কোর দিয়ে শুরু হওয়া যেকোনো ক্লাস ভেরিয়েবলের নাম _ClassName__variableName রূপে পরিবর্তিত হয়ে যায়।
এই নিয়মটি ক্লাসের মেথডগুলোর জন্যও প্রযোজ্য। নিচের কোডটি দেখুন।
উদাহরণ
class Sample:
def __init__(self, a):
self.a = a
# প্রাইভেট মেথড (যথার্থতে নয়)
def __get_a(self):
return self.a
# ক্লাসের ইনস্ট্যান্স তৈরি
sample = Sample(5)
# সঠিক নাম দিয়ে মেথড কল
print(sample._Sample__get_a())
# ভুল নাম দিয়ে মেথড কল
print(sample.__get_a())
আউটপুট
উপরোক্ত কোড রান করলে নিচের ফলাফল পাবেন:
5
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-19-55650c4990c8> in <module>
14
15 # invoking the method with wrong name
---> 16 print(sample.__get_a())
AttributeError: 'Sample' object has no attribute '__get_a'
উপসংহার
ডাবল আন্ডারস্কোর ব্যবহারের উদ্দেশ্য ভেরিয়েবল বা মেথড অ্যাক্সেস বাধা দেওয়া নয়। এর লক্ষ্য হলো নির্দেশ করা যে নির্দিষ্ট ভেরিয়েবল বা মেথডটি ক্লাসের ভিতরেই ব্যবহার করার জন্য বাঁধা। এই টিউটোরিয়াল সম্পর্কে আপনার কোনো প্রশ্ন থাকলে কমেন্ট সেকশনে জানাতে পারেন।