কম্পিউটার টিউটোরিয়াল

পাইথন ক্লোজার (Closures): নেস্টেড ফাংশন এবং এনক্যাপসুলেশনের ধারণা

পাইথন ক্লোজার বুঝতে হলে প্রথমে নেস্টেড ফাংশন এবং পাইথন ক্লাস বুঝতে হবে। সংক্ষেপে, পাইথন ক্লোজারও একটি ফাংশন যা ডেটা কোডের সাথে এনক্যাপসুলেট করে।

পাইথন নেস্টেড ফাংশন

একটি ফাংশনের ভিতরে ডিফাইন করা ফাংশনকে নেস্টেড ফাংশন বলা হয়। নেস্টেড ফাংশন এনক্লোজিং স্কোপের ভেরিয়েবল এক্সেস করতে পারে।

def funcOut():
    print("This is outer function.")
    def funcIn():
        print("This function is defined inside funcOut. \nThis function(funcIn) is called nested function.")
    print("We can call nested function here.")
    funcIn()

print("We are in outer function.\nCalling funcOut.")
funcOut()

আউটপুট

We are in outer function. Calling funcOut.
This is outer function.
We can call nested function here.
This function is defined inside funcOut. This function(funcIn) is called nested function.

funcIn হলো নেস্টেড ফাংশন যা funcOut-এর ভিতরে ডিফাইন করা হয়েছে। আউটপুট থেকে ফাংশন কলিং সিকোয়েন্স বোঝা যায়।

যদি funcOut-থেকে funcIn-এর সব ফাংশনালিটি পেতে চাই, তবে return funcIn করতে হবে, এটাকেই পাইথনে ক্লোজার বলা হয়।

সংক্ষেপে, ক্লোজার হলো একটি ফাংশন (অবজেক্ট) যা তার সৃষ্টি পরিবেশ (এনক্লোজিং স্কোপ) মনে রাখে।

def closureFunc(start):
    def incrementBy(inc):
        return start + inc
    return incrementBy

closure1 = closureFunc(9)
closure2 = closureFunc(90)

print('clsure1(3) = %s' % (closure1(3)))
print('closure2(3) = %s' % (closure2(3)))

আউটপুট

clsure1(3) = 12
closure2(3) = 93

closure1(3) কল করলে ১২ রিটার্ন করে, আর closure2(3) কল করলে ৯৩ রিটার্ন করে। closure1 এবং closure2 দুটো একই ফাংশন incrementBy-কে রেফার করে, কিন্তু দুটি আলাদা ভেরিয়েবল closureFunc আইডেন্টিফায়ারের সাথে বাইন্ডেড থাকায় ফলাফল ভিন্ন হয়।

__closure__ অ্যাট্রিবিউট এবং সেল অবজেক্ট

আরো ইনফরমেশনের জন্য __closure__ অ্যাট্রিবিউট এবং সেল অবজেক্ট ব্যবহার করা যায়:

def closureFunc(start):
    def incrementBy(inc):
        return start + inc
    return incrementBy

a = closureFunc(9)
b = closureFunc(90)

print('type(a)=%s' % (type(a)))
print('a.__closure__=%s' % (a.__closure__))
print('type(a.__closure__[0])=%s' % (type(a.__closure__[0])))
print('a.__closure__[0].cell_contents=%s' % (a.__closure__[0].cell_contents))
print('type(b)=%s' % (type(b)))
print('b.__closure__=%s' % (b.__closure__))
print('type(b.__closure__[0])=%s' % (type(b.__closure__[0])))
print('b.__closure__[0].cell_contents=%s' % (b.__closure__[0].cell_contents))

আউটপুট

type(a) = 
a.__closure__ = 
type(a.__closure__[0]) = 
a.__closure__[0].cell_contents = 9
type(b)=
b.__closure__ = 
type(b.__closure__[0]) = 
b.__closure__[0].cell_contents=90

আউটপুট থেকে দেখা যাচ্ছে, প্রতিটি সেল অবজেক্ট তার সৃষ্টি সময়ের ভ্যালু ধরে রাখে।

  1. পাইথনে প্যাটার্ন প্রিন্ট করার পদ্ধতি

  2. পাইথনে issubset() ফাংশন

  3. পাইথনে intersection() ফাংশন

  4. পাইথনে print() ফাংশন কী এবং কীভাবে কাজ করে?