পাইথনে বিল্ট-ইন ক্লাস থেকে ইনহ্যারিটেন্স

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

আচ্ছা, এই কোড টুকু দেখি:

1
2
3
4
5
6
7
class MyList(list):
    pass


numbers = MyList([1, 2, 3, 4])
numbers.append(5)
print(numbers)

এখানে আমরা MyList কে পাইথনের বিল্ট-ইন ক্লাস list থেকে ইনহ্যারিট করেছি। MyList এ আর কোন কোড লিখি নি। সুতরাং আমাদের MyList এর অবজেক্ট list এর মত আচরন করবে। 5 নম্বর লাইন লক্ষ্য করি। এখানে MyList ইন্সট্যান্সিয়েট করার সময় প্যারামিটার হিসেবে একটি লিস্ট পাস করেছি, কিন্তু MyList এর মাঝে কোন __init__ মেথড লিখি নি। এখানে MyList এর প্যারেন্ট ক্লাস list এর __init__ মেথড কল হচ্ছে। আবার 6 নম্বর লাইনের append মেথডও একই ভাবে প্যারেন্ট ক্লাস থেকে কল হচ্ছে।

কোড টি রান করলে আমরা এরকম আউটপুট পাবো:

[1, 2, 3, 4, 5]

আর্থাৎ আমাদের MyList পাইথনের বিল্ট-ইন list এর মতই আচরণ করছে।

list এর ইনডেক্স শুরু হয় 0 থেকে। এখন আমরা চাই list এর মত এমন একটি ডেটা স্ট্রাকচার MyList বানাতে, যার ইনডেক্স শুরু হবে 1 থেকে। আর বাকি সব ফিচার একই থাকবে। তাহলে আমরা কোড লিখবো এরকম (Python 3):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class MyList(list):

    def __setitem__(self, index, value):
        if index == 0:
            raise IndexError
        if index > 0:
            index -= 1
        super().__setitem__(index, value)

    def __getitem__(self, index):
        if index == 0:
            raise IndexError
        if index > 0:
            index -= 1
        return super().__getitem__(index)


mylist = MyList(['a', 'b', 'c', 'd', 'e'])

mylist[1] = 'apple'
mylist[5] = 'orange'

print(mylist)
print(mylist[1])
print(mylist[5])

MyList এ list এর দুটি ম্যাজিক মেথড __setitem__ এবং __getitem__ অল্টার করেছি। আমরা যখন alist[2] = 5 এরকম কোড লিখি তখন __setitem__ মেথড টি কল হয়। আবার যখন value = alist[2] এরকম কোড লিখি তখন __getitem__ মেথড টি কল হয়।

এখন আমাদের চাহিদা অনুযায়ী index শুরু হতে হবে 1 থেকে। তাই __setitem__ এবং __getitem__ এর ভেতর ওরকম লজিক লিখেছি। এবং তার পর প্যারেন্ট ক্লাস থেকে সংশ্লিষ্ট মেথড কে কল করেছি (অল্টার করেছি)।

আউটপুট দেখে নেই:

['apple', 'b', 'c', 'd', 'orange']
apple
orange

সুতরাং দেখা যাচ্ছে আমাদের Mylist এর ইনডেক্স 1 থেকেই শুরু হচ্ছে, 0 থেকে নয়। মিশন একমপ্লিশড 😎 ।

এরকম ভাবে প্রয়োজনে আমরা পাইথনের অন্যান্য বিল্ট-ইন ক্লাস (যেমন dict, tuple ইত্যাদি) থেকেও ইনহ্যারিট করতে পারি।

Load Comments?