ডেকোরেটর

এই চ্যাপ্টারটি সর্বশেষ হালনাগাদ হয়েছেঃ Tue Nov 28 2017 03:11:13 GMT+0000 (UTC) সময়ে

নাম শুনেই সবাই বুঝতে পারার কথা কোন কিছুর সৌন্দর্য বর্ধন করার মতই কিছু একটা হবে এখন। ডেকোরেটর হচ্ছে সাধারণ রকমেরই একটা ফাংশন যা অন্য আরেকটি ফাংশনকে মডিফাই করে তথা তার কাজকে বর্ধিত বা পরিবর্তিত করে।

অন্য ভাবে বলতে গেলে, যদি কখনো এমন দরকার পরে যে একটা ফাংশনের ফাংশনালিটি একটু পরিবর্তন/পরিবর্ধন করা দরকার কিন্তু আমরা সেই ফাংশনের কোড পরিবর্তন করতে চাচ্ছি না। তখন ডেকোরেটর ব্যবহার করে আমরা সেই কাজটা করতে পারবো।

একটা উদাহরণ -

>>> def my_decorator(func):
...     def decorate():
...         print("--------------")
...         func()
...         print("--------------")
...     return decorate
...
>>> def print_raw():
...     print("Clear Text")
...
>>> decorated_function = my_decorator(print_raw)
>>> decorated_function()
--------------
Clear Text
--------------

ধরুন আমাদের একটা সাধারণ ফাংশন আছে যার নাম print_raw এবং এটি খুব সাধারণ ভাবেই Clear Text এই বাক্যকে প্রিন্ট করে। এখন আমরা চাই যখনই আমি কোথাও Clear Text বাক্যকে প্রিন্ট করবো সেখানে যেন এর আগে পরে একটু স্টাইল যুক্ত হয় --- চিহ্ন দিয়ে। কিন্তু আবার চাচ্ছি না যে, print_raw ফাংশনটার কোড পরিবর্তন করতে।

তখন আমি একটি ডেকোরেটর বানালাম যার নাম my_decorator. এর একটি প্যারামিটার যা হচ্ছে একটি ফাংশন। এই my_decorator এর মধ্যে আমরা আরেকটি ফাংশন তৈরি করেছি যার নাম decorate.

my_decorator এর কাছে আসা ফাংশনকে এই decorate ফাংশনটি এক্সিকিউট করে। কিন্তু তার আগে ও পরে দুটি অতিরিক্ত প্রিন্ট স্টেটমেন্ট যোগ করে স্টাইল করে দেয়। পরিশেষে my_decorator ফাংশনটি এই decorate ফাংশন কে রিটার্ন করে।

এরপর আমরা my_decorator ফাংশন কে কল করেছি এবং এর আর্গুমেন্ট হিসেবে print_raw কে পাঠিয়ে দিয়েছি। এটা মডিফাই হয়ে ফিরে এসে decorated_function ভ্যারিয়েবলে জমা হয়েছে। অতঃপর, decorated_function() কল করে আমরা Clear Text এর স্টাইলড ভার্সন পাই।

ব্যপারটাকে আরেক্টু সুন্দর করার জন্য আমরা ভ্যারিয়েবল রি-অ্যাসাইন এর সুবিধা নিতে পারি অর্থাৎ -

>>> print_raw = my_decorator(print_raw)
>>> print_raw()
--------------
Clear Text
--------------

এবার মনে হচ্ছে print_raw এর নাম ধাম ঠিকি আছে শুধু decorate হয়ে এসেছে :)

@decorator

ধরে নিচ্ছি my_decorator নামের একটি ডেকোরেটর ডিফাইন করা আছে। এখন আমরা চাইলে আমাদের তৈরি যেকোনো নতুন ফাংশনের উপর একে আপ্লাই করতে পারি। যেমন, আমরা যদি কোথাও নিচের মত একটা ফাংশন লিখি,

def print_text():
    print("Hello World!")

এবং চাই যে এর উপর আমাদের decorator এর স্টাইল আপ্লাই হোক। তাহলে খুব সহজ ভাবে আমরা নিচের মত করে একে একটি decorator এর আওতাধীন করতে পারি,

@my_decorator
def print_text():
    print("Hello World!")

তাহলে যখনই print_text কল করা হবে তখনি নিচের মত আউটপুট আসবে,

--------------
Hello World!
--------------

সংকলন - নুহিল মেহেদী