অবজেক্ট হিসেবে ফাংশন

একটা কথা বলা হয় = "পাইথনে সব কিছুই অবজেক্ট"। প্রত্যেকটি অবজেক্টেরই কিছু অ্যাট্রিবিউট ও মেথড থাকে। যেমন, আমরা যখনই একটি স্ট্রিং ভ্যারিয়েবল তৈরি করি a = "Abc" এভাবে, তখন যদি type(a) দেখার চেষ্টা করি তাহলে আউটপুট পাবো <class 'str'> অর্থাৎ এই a অবজেক্টটি str ক্লাসের একটি অবজেক্ট এবং এর কিছু অ্যাট্রিবিউট ও মেথড আছে। যেমন - lower, upper ইত্যাদি, যেগুলো ব্যবহার করে আমরা a কে নিয়ে বিভিন্ন কাজ করতে পারি।

ক্লাস, অবজেক্ট, অ্যাট্রিবিউট, মেথড নিয়ে বিস্তারিত আলোচনা আছে অবজেক্ট ওরিয়েন্টেড সেকশনে

ফাংশনও একটি অবজেক্ট অর্থাৎ এরও কিছু অ্যাট্রিবিউট ও মেথড আছে। যেমন একটি ফাংশনকে ডিফাইন করার সাথে সাথেই তার __doc__ নামের অ্যাট্রিবিউট তৈরি হয় যার মাধ্যমে একটি ফাংশনের ডক স্ট্রিং অ্যাক্সেস করা যায়। অন্যান্য সাধারণ ভ্যারিয়েবলের ভ্যালুর মত কোন একটি ফাংশনকেও একটি ভ্যারিয়েবলে অ্যাসাইন বা স্টোর করা যায়।

উদাহরণ,

def add_explanation(line):
    return line + '!'

update_line = add_explanation

print(update_line("Hello World"))

আউটপুট,

Hello World!

উপরের প্রোগ্রামে প্রথমে add_explanation ফাংশনটিকে update_line ভ্যারিয়েবলে অ্যাসাইন করা হয়েছে। এরপর, যেখানে add_explanation ফাংশনের দরকার পরেছে সেখানে তাকে update_line নামে কল করা হয়েছে। এভাবে বস্তুত add_explanation -টাই কল হচ্ছে। আরেকটু পরীক্ষা করার জন্য আমরা যদি print(update_line) স্টেটমেন্টটি এক্সিকিউট করি তাহলে আউটপুট আসবে <function add_explanation at 0x10dbf5668>

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

def beautify(text):
    return text + '!!!'


def make_line(func, words):
    return "Hello " + func(words)


print(make_line(beautify, "world"))

আউটপুট,

Hello world!!!

উপরের প্রোগ্রামটি একটু বিশ্লেষণ করা যাকঃ ধরে নিচ্ছি beautify ফাংশনের কাজ হচ্ছে এর কাছে যাই দেয়া হয় তার সাথে তিনটি বিস্ময় চিহ্ন যুক্ত করে রিটার্ন করে। আবার আমাদের একটি ফাংশন আছে make_line যা দিয়ে একটি বাক্য তৈরি করা হয়। কিন্তু আমরা চাই এর মধ্যে বাক্য তৈরির সময়ই শেষ শব্দের সাথে কিছু বিস্ময় চিহ্ন জুড়ে দিতে। তো, যেহেতু বিস্ময় চিহ্ন জুড়ে দেয়ার ফাংশন আমাদের বানানোই আছে তাই ওই ফাংশনকে make_line এর একটি আর্গুমেন্ট বা চাহিদা হিসেবে উল্লেখ করতে পারি। অর্থাৎ make_line কে কল করতে হলে এর আর্গুমেন্ট হিসেবে একটি ফাংশন এবং একটি ডাটা (ধরে নিচ্ছি একটি শব্দ) পাঠাতে হবে। যাতে করে প্রয়োজনে সে ওই beautify ফাংশনকে তার বডির মধ্যে থেকে কল করে ব্যবহার করতে পারে।

make_line ফাংশনের ডেফিনেশনে এর কাছে আসা ফাংশনকে func নামে রিসিভ করা হয়েছে এবং এর বডির মধ্যে সেই নামেই ব্যবহার করা হয়েছে সাধারণভাবে পাস করা ভ্যারিয়েবলের মত আর তার মাধ্যমে বস্তুত beautify ফাংশন কল হয়েছে।