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

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

> ক্লাস, অবজেক্ট, অ্যাট্রিবিউট, মেথড নিয়ে বিস্তারিত আলোচনা আছে [অবজেক্ট ওরিয়েন্টেড সেকশনে](https://python.howtocode.dev/oop-python)

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

উদাহরণ,

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

update_line = add_explanation

print(update_line("Hello World"))
```

আউটপুট,

```python
Hello World!
```

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

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

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


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


print(make_line(beautify, "world"))
```

আউটপুট,

```python
Hello world!!!
```

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

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