পাইথনে ডেকোরেটরস

পাইথনে ডেকোরেটরস

এই প্রবন্ধে পাইথনে ডেকোরেটরস ব্যাখ্যা করা হয়েছে।

YouTube Video

পাইথনে ডেকোরেটরস

পাইথন ডেকোরেটরস এক শক্তিশালী বৈশিষ্ট্য যারা ফাংশন বা মেথডকে অতিরিক্ত কার্যকারিতা যোগ করতে ব্যবহৃত হয়। ডেকোরেটর আপনাকে নতুন কার্যকারিতা যোগ করতে দেয় কোন পূর্ববর্তী কোড সংশোধন না করেই, যাতে কোড পুনর্ব্যবহারযোগ্যতা এবং রক্ষণাবেক্ষণ উন্নত হয়।

ডেকোরেটরের ভিত্তি

পাইথন ডেকোরেটরস একটি ফাংশনকে আর্গুমেন্ট হিসাবে নিয়ে অতিরিক্ত কার্যকারিতার সাথে একটি নতুন ফাংশন ফিরিয়ে দিয়ে কাজ করে। ডেকোরেটর ব্যবহার করে আপনি সহজেই ফাংশনে প্রি-প্রসেসিং বা পোস্ট-প্রসেসিং যোগ করতে পারেন।

ডেকোরেটর ছাড়া, একটি ফাংশনের আচরণ পরিবর্তনের জন্য সরাসরি ফাংশনটি সম্পাদনা করার প্রয়োজন হয়। ডেকোরেটরের মাধ্যমে, আপনি আসল কার্যকরকে সংশোধন না করেই কার্যকারিতা বাড়াতে পারেন।

ডেকোরেটরের মৌলিক কাঠামো

 1def my_decorator(func):
 2    def wrapper():
 3        print("Before the function call")
 4        func()
 5        print("After the function call")
 6    return wrapper
 7
 8@my_decorator
 9def say_hello():
10    print("Hello!")
11
12say_hello()

এই উদাহরণে, my_decorator ফাংশন একটি ডেকোরেটর হিসাবে কাজ করে, যা say_hello ফাংশনকে মোড়ক দেয়। @my_decorator সিনট্যাক্স ব্যবহার করে ডেকোরেটর প্রয়োগ করা হয়, এবং যখন say_hello() ডাকা হয়, তখন ডেকোরেটরের দ্বারা সরবরাহিত প্রি- এবং পোস্ট-প্রসেসিং স্বয়ংক্রিয়ভাবে কার্যকর হয়।

ডেকোরেটর কিভাবে কাজ করে

ডেকোরেটরগুলি নিম্নলিখিত ধাপে কাজ করে।

  1. ডেকোরেটর একটি ফাংশন (বা মেথড) আর্গুমেন্ট হিসাবে গ্রহণ করে।

  2. এটি আসল ফাংশনটি চালানোর জন্য একটি র‍্যাপার ফাংশন সংজ্ঞায়িত করে।

  3. র‍্যাপার ফাংশন মূল ফাংশনটি কার্যকর করার আগে বা পরে অতিরিক্ত প্রক্রিয়াজাতকরণ করে।

  4. ডেকোরেটর র‍্যাপার ফাংশনটি ফিরিয়ে দেয়। ফলস্বরূপ, আসল ফাংশনটি একটি নতুন, সজ্জিত ফাংশন দিয়ে প্রতিস্থাপিত হয়।

আর্গুমেন্ট সহ ফাংশনের জন্য ডেকোরেটর

আর্গুমেন্ট সহ একটি ফাংশনে ডেকোরেটর প্রয়োগ করার সময়, র‍্যাপার ফাংশনটিকে সেই আর্গুমেন্টগুলি গ্রহণ করার জন্য সামঞ্জস্য করতে হবে।

 1def my_decorator(func):
 2    def wrapper(*args, **kwargs):
 3        print("Before the function call")
 4        result = func(*args, **kwargs)
 5        print("After the function call")
 6        return result
 7    return wrapper
 8
 9@my_decorator
10def greet(name):
11    print(f"Hello, {name}!")
12
13greet("Alice")

*args এবং **kwargs ব্যবহার করে যেকোনো সংখ্যক আর্গুমেন্ট এবং কিওয়ার্ড আর্গুমেন্ট গ্রহণকারী ফাংশন পরিচালনা করা সম্ভব। এটি ডেকোরেটরগুলিকে যেকোনো ধরণের আর্গুমেন্ট সহ ফাংশনের উপর সাধারণভাবে প্রয়োগ করার অনুমতি দেয়।

ডেকোরেটর প্রয়োগের উদাহরণসমূহ

লগিং এর জন্য ডেকোরেটর

ডেকোরেটর প্রায়শই লগিং ফিচার যুক্ত করার জন্য ব্যবহৃত হয়। উদাহরণস্বরূপ, যদি একটি ডেকোরেটর তৈরি করা হয় যা ফাংশনটি কার্যকর করার আগে এবং পরে লগ করে, তবে এটি ফাংশনটি কখন কল করা হয়েছে এবং এটি পুরো করতে কতক্ষণ সময় নিতে পারে তা রেকর্ড করতে পারে।

 1import time
 2
 3def log_time(func):
 4    def wrapper(*args, **kwargs):
 5        start_time = time.time()
 6        print(f"Calling function '{func.__name__}'...")
 7        result = func(*args, **kwargs)
 8        end_time = time.time()
 9        print(f"Function '{func.__name__}' completed in {end_time - start_time} seconds")
10        return result
11    return wrapper
12
13@log_time
14def long_task(duration):
15    time.sleep(duration)
16    print("Task completed!")
17
18long_task(2)

এই উদাহরণে, log_time ডেকোরেটর একটি ফাংশনের কার্যকর সময় পরিমাপ করে এবং এটি লগ হিসাবে আউটপুট করে। long_task ফাংশনটি ডেকোরেটর দ্বারা মোড়ানো হয় এবং এর কার্যকর সময় রানটাইম-এ রেকর্ড করা হয়।

অনুমতি ব্যবস্থাপনার জন্য ডেকোরেটর

ডেকোরেটর অনুমতি ব্যবস্থাপনার জন্যও ব্যবহৃত হতে পারে। উদাহরণস্বরূপ, ব্যবহারকারীর নির্দিষ্ট অনুমতি আছে কি না তা যাচাই করে প্রসেসিং সীমাবদ্ধ করা যেতে পারে।

 1def requires_permission(user_role):
 2    def decorator(func):
 3        def wrapper(*args, **kwargs):
 4            if user_role != "admin":
 5                print("Permission denied!")
 6                return
 7            return func(*args, **kwargs)
 8        return wrapper
 9    return decorator
10
11@requires_permission("admin")
12def delete_user(user_id):
13    print(f"User {user_id} has been deleted.")
14
15delete_user(123)  # Executed
16delete_user = requires_permission("guest")(delete_user)
17delete_user(456)  # Permission denied!

requires_permission ডেকোরেটর একটি ব্যবহারকারীর ভূমিকার উপর ভিত্তি করে একটি ফাংশনের কার্যকর সীমাবদ্ধ করে। এই ধরণের লজিক ডেকোরেটরের মধ্যে একীভূত করলে, আপনি অনুমতি ব্যবস্থাপনার লজিককে আপনার কোডের বিভিন্ন স্থানে ছড়িয়ে পড়া থেকে রুখতে পারেন এবং পড়ার যোগ্যতা বাড়াতে পারেন।

ডেকোরেটর নেস্টিং

একাধিক ডেকোরেটর প্রয়োগ করা সম্ভব। যখন একটি ফাংশনে একাধিক ডেকোরেটর প্রয়োগ করা হয়, তারা উপরে থেকে নিচে ক্রমানুসারে কার্যকর হয়।

 1def uppercase(func):
 2    def wrapper(*args, **kwargs):
 3        result = func(*args, **kwargs)
 4        return result.upper()
 5    return wrapper
 6
 7def exclaim(func):
 8    def wrapper(*args, **kwargs):
 9        result = func(*args, **kwargs)
10        return result + "!"
11    return wrapper
12
13@uppercase
14@exclaim
15def greet(name):
16    return f"Hello, {name}"
17
18print(greet("Alice"))  # "HELLO, ALICE!"

এই উদাহরণে, greet ফাংশনে দুটি ডেকোরেটর প্রয়োগ করা হয়েছে। @exclaim ডেকোরেটর স্ট্রিংয়ের শেষে একটি বিস্ময়বোধক চিহ্ন যুক্ত করে এবং তারপর @uppercase স্ট্রিংটিকে বড় হাতের অক্ষরে রূপান্তরিত করে।

ক্লাস মেথডের জন্য ডেকোরেটর

ডেকোরেটর ক্লাস মেথডের সাথেও ব্যবহার করা যেতে পারে। এটি বিশেষভাবে কার্যকর যখন আপনি একটি ক্লাসের মেথডের আচরণ নিয়ন্ত্রণ করতে চান। ক্লাস মেথডে ডেকোরেটর প্রয়োগ করার সময়, self বা cls এর মতো আর্গুমেন্টগুলোর প্রতি মনোযোগী হওয়া প্রয়োজন।

 1def log_method_call(func):
 2    def wrapper(self, *args, **kwargs):
 3        print(f"Calling method '{func.__name__}'...")
 4        return func(self, *args, **kwargs)
 5    return wrapper
 6
 7class MyClass:
 8    @log_method_call
 9    def greet(self, name):
10        print(f"Hello, {name}")
11
12obj = MyClass()
13obj.greet("Bob")

এই উদাহরণে, log_method_call ডেকোরেটরটি greet মেথডে প্রয়োগ করা হয়েছে যাতে মেথডটি কল হলে একটি লগ আউটপুট হয়।

ডেকোরেটর ব্যবহারে সতর্কতা

ডেকোরেটর ব্যবহার করার সময় কিছু বিষয় বিবেচনা করতে হবে। ডেকোরেটর মূল ফাংশনের নাম ও ডকুমেন্টেশন স্ট্রিং (যেমন, __name__ বা __doc__) পরিবর্তন করতে পারে, তাই এই তথ্য সংরক্ষণের জন্য functools.wraps ব্যবহার করার সুপারিশ করা হয়।

1import functools
2
3def my_decorator(func):
4    @functools.wraps(func)
5    def wrapper(*args, **kwargs):
6        print("Before the function call")
7        return func(*args, **kwargs)
8    return wrapper

@functools.wraps ব্যবহার করলে, মূল ফাংশনের মেটাডেটা সঠিকভাবে র‍্যাপার ফাংশনে পাস হয় তা নিশ্চিত হয়।

সারসংক্ষেপ

পাইথন ডেকোরেটর একটি অত্যন্ত শক্তিশালী টুল যা ফাংশন এবং মেথডগুলিতে সংক্ষিপ্তভাবে অতিরিক্ত কার্যকারিতা যোগ করতে দেয়। সেগুলি বিভিন্ন পরিস্থিতিতে কোডের পুনরাবৃত্তি হ্রাস করতে এবং রক্ষণাবেক্ষণযোগ্যতা ও পুনঃব্যবহারযোগ্যতা উন্নত করতে ব্যবহার করা যেতে পারে। ডেকোরেটর কিভাবে কাজ করে তা বুঝে, আপনি আরও দক্ষ এবং নমনীয় কোড লিখতে পারবেন।

আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।

YouTube Video