Python-এ বেশ কিছু অ্যাডভান্সড টপিক রয়েছে, যা প্রোগ্রামিং দক্ষতা বৃদ্ধি করতে এবং বড় প্রকল্পগুলো আরও দক্ষভাবে পরিচালনা করতে সাহায্য করে। এই টপিকগুলির মাধ্যমে Python প্রোগ্রামাররা আরও পেশাদার কোড লিখতে পারে এবং অ্যাপ্লিকেশনগুলো আরও কার্যকরী এবং স্কেলেবল করতে পারে। এখানে Python-এর কিছু গুরুত্বপূর্ণ অ্যাডভান্সড টপিক নিয়ে আলোচনা করা হলো:
১. ডেকোরেটর (Decorators)
ডেকোরেটর হল একটি ফাংশন, যা আরেকটি ফাংশনের উপর কার্যকর হয় এবং মূল ফাংশনের কার্যক্ষমতা পরিবর্তন না করেই নতুন ফিচার যোগ করে। এটি সাধারণত @ সিম্বল ব্যবহার করে ফাংশনের উপরে লেখা হয়।
উদাহরণ
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
আউটপুট:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
২. জেনারেটর (Generators)
জেনারেটর ফাংশন ব্যবহার করে ইটারেটরের মতো একের পর এক মান উৎপন্ন করতে পারে। yield কীওয়ার্ড ব্যবহার করে প্রতিবার একটি করে মান প্রদান করা হয়, যা মেমরি ব্যবহারের ক্ষেত্রে খুবই কার্যকরী।
উদাহরণ
def my_generator():
yield 1
yield 2
yield 3
gen = my_generator()
for value in gen:
print(value)
আউটপুট:
1
2
3
৩. কনটেক্সট ম্যানেজার (Context Managers)
Context Managers প্রায়ই ফাইল পরিচালনার মতো ক্ষেত্রে ব্যবহৃত হয়। এটি with স্টেটমেন্টের মাধ্যমে শুরু হয় এবং ফাইল বা রিসোর্সকে সঠিকভাবে বন্ধ করে দেয়, এমনকি যদি কোন এক্সসেপশন ঘটে।
উদাহরণ
with open('example.txt', 'w') as file:
file.write("Hello, World!")
# এখানে ফাইলটি স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে
আপনি কাস্টম কনটেক্সট ম্যানেজারও তৈরি করতে পারেন।
class MyContext:
def __enter__(self):
print("Entering the context...")
def __exit__(self, exc_type, exc_value, traceback):
print("Exiting the context...")
with MyContext():
print("Inside the context")
আউটপুট:
Entering the context...
Inside the context
Exiting the context...
৪. মাল্টিথ্রেডিং এবং মাল্টিপ্রসেসিং
Python এ মাল্টিথ্রেডিং এবং মাল্টিপ্রসেসিং ব্যবহার করে একাধিক কাজ একসাথে সম্পাদন করা যায়। এটি বড় অ্যাপ্লিকেশনগুলির কর্মদক্ষতা বৃদ্ধি করে।
মাল্টিথ্রেডিং উদাহরণ
import threading
def print_numbers():
for i in range(5):
print(i)
# দুটি থ্রেড তৈরি
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_numbers)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
মাল্টিপ্রসেসিং উদাহরণ
from multiprocessing import Process
def print_numbers():
for i in range(5):
print(i)
# দুটি প্রসেস তৈরি
process1 = Process(target=print_numbers)
process2 = Process(target=print_numbers)
process1.start()
process2.start()
process1.join()
process2.join()
৫. মেটাক্লাস (Metaclasses)
Python-এ মেটাক্লাস হলো ক্লাস তৈরির জন্য ব্যবহৃত ক্লাস। এটি উন্নত এবং জটিল কাঠামো তৈরি করতে সহায়ক। সাধারণত এটি খুব কম ব্যবহৃত হয় তবে এটি বেশ কার্যকরী হতে পারে।
উদাহরণ
class MyMeta(type):
def __new__(cls, name, bases, dct):
print(f"Creating class {name}")
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=MyMeta):
pass
আউটপুট:
Creating class MyClass
৬. ফাংশনাল প্রোগ্রামিং (Functional Programming)
Python-এ ফাংশনাল প্রোগ্রামিং কনসেপ্টের জন্য lambda, map(), filter(), reduce() ইত্যাদি ফাংশন রয়েছে। এই ফাংশনগুলির মাধ্যমে ডেটা প্রক্রিয়াকরণ সহজ হয়।
উদাহরণ
# lambda ব্যবহার করে ছোট ফাংশন তৈরি
square = lambda x: x * x
print(square(5)) # Output: 25
# map ব্যবহার
numbers = [1, 2, 3, 4]
squared_numbers = list(map(lambda x: x * x, numbers))
print(squared_numbers) # Output: [1, 4, 9, 16]
# filter ব্যবহার
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # Output: [2, 4]
৭. এক্সসেপশন হ্যান্ডলিং (Exception Handling)
Python-এ try, except, finally এবং raise ব্যবহার করে এক্সসেপশন হ্যান্ডলিং করা হয়, যা অ্যাপ্লিকেশনকে আরও স্টেবল করে।
উদাহরণ
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
finally:
print("Execution completed")
আউটপুট:
Cannot divide by zero!
Execution completed
৮. প্যাকেজ এবং মডিউল
Python-এ বড় প্রজেক্ট ব্যবস্থাপনার জন্য কোডকে বিভিন্ন মডিউল এবং প্যাকেজে বিভক্ত করা হয়।
- মডিউল: একটি
.pyফাইল যা ফাংশন, ক্লাস বা ভ্যারিয়েবল ধারণ করে। - প্যাকেজ: একটি ফোল্ডার যা একাধিক মডিউল ধারণ করে এবং
__init__.pyফাইল সহ থাকে।
# example_module.py
def greet(name):
return f"Hello, {name}"
# main.py
import example_module
print(example_module.greet("Alice")) # Output: Hello, Alice
৯. টাইপ হিন্টিং (Type Hinting)
Python-এ টাইপ হিন্টিং কোডের পঠনযোগ্যতা বৃদ্ধি করে।
উদাহরণ
def greet(name: str) -> str:
return f"Hello, {name}"
print(greet("Alice"))
১০. লাইব্রেরি ব্যবহারে অ্যাডভান্সড টেকনিক
Python-এ ডেটা প্রক্রিয়াকরণ এবং ওয়েব স্ক্র্যাপিংয়ের মতো বিভিন্ন কাজে উন্নত লাইব্রেরি রয়েছে। যেমন:
- Pandas: ডেটা ম্যানিপুলেশনের জন্য।
- NumPy: গাণিতিক অপারেশনের জন্য।
- BeautifulSoup এবং Scrapy: ওয়েব স্ক্র্যাপিং এর জন্য।
- SQLAlchemy: ডেটাবেস ORM-এর জন্য।
উপসংহার
Python-এর অ্যাডভান্সড টপিকগুলি দক্ষ প্রোগ্রামিং এবং বড় প্রজেক্ট ব্যবস্থাপনায় সাহায্য করে। ডেকোরেটর, জেনারেটর, মাল্টিথ্রেডিং, মেটাক্লাস, এক্সসেপশন হ্যান্ডলিং, এবং টাইপ হিন্টিংয়ের মতো টপিকগুলো Python প্রোগ্রামারদের আরও কার্যকরী এবং পেশাদার কোড লিখতে সহায়তা করে।
মাল্টিথ্রেডিং এবং কনকারেন্সি হলো প্রোগ্রামিংয়ের দুটি গুরুত্বপূর্ণ ধারণা, যা কোডের পারফরম্যান্স উন্নত করতে এবং একাধিক কাজ একইসাথে সম্পাদন করতে সহায়ক। পাইথনে মাল্টিথ্রেডিং এবং কনকারেন্সি ব্যবহার করে প্রোগ্রামের একাধিক অংশ বা ফাংশন একই সাথে চালানো যায়, যা সময় এবং রিসোর্সের সঠিক ব্যবহার নিশ্চিত করে।
মাল্টিথ্রেডিং (Multithreading)
মাল্টিথ্রেডিং হলো একটি প্রক্রিয়া যেখানে একটি প্রোগ্রাম একই সময়ে একাধিক থ্রেড চালাতে পারে। একটি থ্রেড হলো প্রোগ্রামের একটি ছোট ইউনিট, যা স্বতন্ত্রভাবে কাজ করতে পারে। মাল্টিথ্রেডিং সাধারণত আই/ও-ভিত্তিক কাজের জন্য খুবই উপযোগী, কারণ এটি CPU রিসোর্সের অপেক্ষা না করে অন্যান্য কাজ চালাতে দেয়।
মাল্টিথ্রেডিং উদাহরণ
import threading
import time
# একটি সাধারণ ফাংশন যা একটি নির্দিষ্ট সময়ের জন্য ঘুমায়
def print_numbers():
for i in range(1, 6):
print(f"Number: {i}")
time.sleep(1)
# থ্রেড তৈরি এবং শুরু করা
thread = threading.Thread(target=print_numbers)
thread.start()
# থ্রেডটি অন্য কাজের সাথে একই সাথে চলবে
print("This will print while the thread is running.")
থ্রেড ব্যবহার করার সুবিধা
- একাধিক কাজ এক সাথে করতে সক্ষম
- আই/ও-বাউন্ড কাজের পারফরম্যান্স উন্নত করে
- দ্রুত রেসপন্সের জন্য কার্যকরী
থ্রেড ব্যবহার করার সমস্যা
- থ্রেডের মধ্যে ডেটা শেয়ার করা জটিল এবং ডেটা কনসিস্টেন্সি নিশ্চিত করা কঠিন
- ডেডলক (Deadlock) এবং রেস কন্ডিশনের (Race Condition) মত সমস্যা হতে পারে
কনকারেন্সি (Concurrency)
কনকারেন্সি হলো একই সময়ে একাধিক কাজ সম্পন্ন করার ধারণা। এটি একাধিক কাজের মধ্যে দ্রুত স্যুইচিং করে কাজ করে। কনকারেন্সি সাধারণত মাল্টিপ্রসেসিং বা মাল্টিথ্রেডিংয়ের মাধ্যমে অর্জন করা যায়।
কনকারেন্ট প্রোগ্রামিং উদাহরণ
import concurrent.futures
import time
# ফাংশন যা এক সেকেন্ড অপেক্ষা করে এবং নম্বর প্রিন্ট করে
def print_number(num):
time.sleep(1)
return f"Number: {num}"
# থ্রেড পুল এক্সিকিউটর ব্যবহার করে কনকারেন্ট এক্সিকিউশন
with concurrent.futures.ThreadPoolExecutor() as executor:
results = [executor.submit(print_number, i) for i in range(1, 6)]
for future in concurrent.futures.as_completed(results):
print(future.result())
এখানে, ThreadPoolExecutor ব্যবহার করে পাঁচটি কাজ সমান্তরালে (কনকারেন্টলি) চালানো হয়েছে। প্রতিটি কাজ এক সেকেন্ডে সম্পন্ন হলেও, কনকারেন্টভাবে চলার কারণে সময় অনেক কম লাগে।
মাল্টিপ্রসেসিং (Multiprocessing)
মাল্টিপ্রসেসিং মাল্টিকোর CPU ব্যবহার করে কাজ সম্পন্ন করার প্রক্রিয়া। এটি প্রতিটি প্রসেসকে সম্পূর্ণ আলাদা মেমোরি স্পেস প্রদান করে, যা থ্রেডের চেয়ে নিরাপদ এবং দ্রুত।
মাল্টিপ্রসেসিং উদাহরণ
from multiprocessing import Process
# একটি সাধারণ ফাংশন যা নম্বর প্রিন্ট করে
def print_numbers():
for i in range(1, 6):
print(f"Number: {i}")
# মাল্টিপ্রসেসিং ব্যবহার করে ফাংশন চালানো
process = Process(target=print_numbers)
process.start()
# মেইন প্রসেসে অন্যান্য কাজ সম্পাদন করা
print("This will print while the process is running.")
process.join()
মাল্টিপ্রসেসিং বনাম মাল্টিথ্রেডিং
| বৈশিষ্ট্য | মাল্টিপ্রসেসিং | মাল্টিথ্রেডিং |
|---|---|---|
| প্রসেস | প্রতিটি প্রসেস আলাদা মেমোরি স্পেস নিয়ে কাজ করে | থ্রেড একই মেমোরি স্পেস শেয়ার করে |
| গতি | CPU-বাউন্ড কাজের জন্য উপযোগী | I/O-বাউন্ড কাজের জন্য উপযোগী |
| সিদ্ধান্ত | থ্রেডের চেয়ে নিরাপদ, কিন্তু কিছুটা ধীর | দ্রুত, কিন্তু রেস কন্ডিশন এবং ডেডলকের ঝুঁকি |
| রিসোর্স | বেশি রিসোর্স ব্যবহার করে | তুলনামূলকভাবে কম রিসোর্স ব্যবহার করে |
গ্লোবাল ইন্টারপ্রেটার লক (GIL) এবং মাল্টিথ্রেডিং
পাইথনে একটি গ্লোবাল ইন্টারপ্রেটার লক (GIL) রয়েছে, যা এক সময়ে এক থ্রেড চালানোর অনুমতি দেয়। এটি CPU-বাউন্ড কাজের ক্ষেত্রে মাল্টিথ্রেডিংকে সীমিত করে, কিন্তু I/O-বাউন্ড কাজের জন্য মাল্টিথ্রেডিং কার্যকর।
সারসংক্ষেপ
- মাল্টিথ্রেডিং: একাধিক থ্রেড তৈরি করে I/O-বাউন্ড কাজ দ্রুত করার প্রক্রিয়া।
- মাল্টিপ্রসেসিং: একাধিক প্রসেস তৈরি করে CPU-বাউন্ড কাজ দ্রুত করার প্রক্রিয়া।
- কনকারেন্সি: একাধিক কাজ সমান্তরালে করার প্রক্রিয়া, যা মাল্টিপ্রসেসিং বা মাল্টিথ্রেডিং দিয়ে অর্জন করা যায়।
মাল্টিথ্রেডিং এবং কনকারেন্সি প্রোগ্রামিং কোডের কার্যকারিতা এবং দক্ষতা বাড়ায়, যা বড় বড় কাজ কম সময়ে সম্পাদন করতে সহায়ক।
Python-এ জেনারেটর এবং ইটারেটর দুটি গুরুত্বপূর্ণ কনসেপ্ট, যা মেমরি এবং কম্পিউটিং পারফরম্যান্সের উন্নতিতে সহায়ক। তারা মূলত লুপের মাধ্যমে তথ্য পুনরাবৃত্তি করে বের করার জন্য ব্যবহৃত হয়, কিন্তু তাদের কাজের ধরণ কিছুটা আলাদা। নিচে এই দুটি ধারণা বিস্তারিত ব্যাখ্যা করা হলো।
ইটারেটর (Iterator)
ইটারেটর একটি অবজেক্ট, যা একবারে একটি এলিমেন্ট বের করে আনার জন্য Python-এর __iter__() এবং __next__() মেথড সংজ্ঞায়িত করে। এটি সাধারণত বড় ডেটাসেট থেকে তথ্য পুনরাবৃত্তি করে বের করতে ব্যবহৃত হয়।
ইটারেটর তৈরি এবং ব্যবহার
যেকোনো ইটারেবল অবজেক্ট যেমন তালিকা, টাপল, স্ট্রিং ইত্যাদি থেকে ইটারেটর তৈরি করা সম্ভব। iter() ফাংশন ব্যবহার করে আমরা একটি ইটারেটর তৈরি করতে পারি এবং next() ফাংশন দিয়ে একের পর এক এলিমেন্ট বের করতে পারি।
# একটি তালিকা থেকে ইটারেটর তৈরি করা
my_list = [1, 2, 3, 4]
my_iterator = iter(my_list)
# next() ফাংশন দিয়ে ইটারেটরের এলিমেন্ট বের করা
print(next(my_iterator)) # Output: 1
print(next(my_iterator)) # Output: 2
print(next(my_iterator)) # Output: 3
print(next(my_iterator)) # Output: 4
# পরবর্তীতে next() কল করলে StopIteration এরর আসবে
কাস্টম ইটারেটর তৈরি
Python-এ আমরা __iter__() এবং __next__() মেথড সংজ্ঞায়িত করে একটি কাস্টম ইটারেটর ক্লাস তৈরি করতে পারি।
class MyIterator:
def __init__(self, max_value):
self.max = max_value
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current < self.max:
self.current += 1
return self.current - 1
else:
raise StopIteration
# কাস্টম ইটারেটর ব্যবহার
my_iter = MyIterator(5)
for value in my_iter:
print(value) # Output: 0, 1, 2, 3, 4
জেনারেটর (Generator)
জেনারেটর ইটারেটরের একটি বিশেষ ধরনের ফর্ম যা ফাংশনের মাধ্যমে তৈরি করা হয় এবং yield কীওয়ার্ড ব্যবহার করে প্রতিটি মান প্রদান করে। এটি ডেটা একবারে একসাথে তৈরি না করে প্রতিটি চাহিদা অনুযায়ী এলিমেন্ট তৈরি করে, ফলে মেমরি সাশ্রয়ী হয়। যখনই yield ব্যবহার করা হয়, তখন ফাংশনটি তার বর্তমান অবস্থা স্মরণ করে এবং পুনরায় কল করা হলে সেখান থেকে পরবর্তী মান প্রদান করে।
জেনারেটর তৈরি করা
# একটি জেনারেটর ফাংশন যা নির্দিষ্ট সংখ্যক ক্রম প্রদান করে
def my_generator(n):
i = 0
while i < n:
yield i
i += 1
# জেনারেটর ফাংশন ব্যবহার
gen = my_generator(5)
for value in gen:
print(value) # Output: 0, 1, 2, 3, 4
yield বনাম return
- yield: ফাংশনটিকে জেনারেটর হিসেবে গড়ে তোলে এবং প্রতিবার যখন এটি কল করা হয় তখন পূর্বের স্থানে ফিরে আসে।
- return: ফাংশনের কাজ সম্পন্ন হলে ফাংশনটি শেষ করে এবং একটি একক মান প্রদান করে।
ইটারেটর এবং জেনারেটরের মধ্যে পার্থক্য
| বৈশিষ্ট্য | ইটারেটর (Iterator) | জেনারেটর (Generator) |
|---|---|---|
| তৈরি পদ্ধতি | __iter__() এবং __next__() মেথড দিয়ে তৈরি | yield ব্যবহার করে ফাংশনের মাধ্যমে তৈরি |
| মেমরি ব্যবহার | সম্পূর্ণ ডেটা মেমরিতে রাখে | প্রয়োজন অনুযায়ী ডেটা তৈরি করে (মেমরি সাশ্রয়ী) |
| ব্যবহার | সাধারণভাবে iter() এবং next() দিয়ে ব্যবহৃত | সরাসরি for লুপের সাথে ব্যবহারযোগ্য |
| স্টেট রিমেম্বার | নিজস্ব স্টেট ম্যানেজ করে | yield এর মাধ্যমে ফাংশনের স্টেট স্মরণ করে |
উদাহরণ: জেনারেটর দিয়ে ইনফাইনাইট সিকোয়েন্স তৈরি করা
# একটি ইনফাইনাইট সিকোয়েন্স জেনারেটর যা একের পর এক মান প্রদান করে
def infinite_sequence():
num = 0
while True:
yield num
num += 1
# ইনফাইনাইট সিকোয়েন্স ব্যবহার
gen = infinite_sequence()
for _ in range(5):
print(next(gen)) # Output: 0, 1, 2, 3, 4
উপসংহার
ইটারেটর এবং জেনারেটর দুটি খুবই শক্তিশালী কনসেপ্ট যা বড় আকারের ডেটাসেট নিয়ে কাজ করার সময় মেমরি এবং কম্পিউটিং পারফরম্যান্সের উন্নতি করতে সাহায্য করে। ইটারেটর সরাসরি ব্যবহার করা যায়, কিন্তু জেনারেটর স্মার্টভাবে মেমরি সাশ্রয় করে বড় ডেটাসেট নিয়ে কাজ করতে সক্ষম।
ডেকোরেটর (Decorator) পাইথনের একটি শক্তিশালী এবং নমনীয় বৈশিষ্ট্য, যা ফাংশন বা মেথডের আচরণ পরিবর্তন করতে বা প্রসারিত করতে ব্যবহার করা হয়। ডেকোরেটর মূলত একটি ফাংশনকে ইনপুট হিসেবে গ্রহণ করে এবং আরেকটি ফাংশন রিটার্ন করে। এটি মূল ফাংশনের কোনো পরিবর্তন না করে নতুন ফাংশনালিটি যোগ করতে সহায়ক।
ডেকোরেটরের গঠন
ডেকোরেটরের মাধ্যমে একটি ফাংশন বা মেথডের উপর অতিরিক্ত কার্যকারিতা যোগ করা যায়। এটি @decorator_name সিনট্যাক্স দিয়ে ব্যবহার করা হয়।
@decorator_name
def function_to_decorate():
pass
নিচে একটি সাধারণ উদাহরণসহ ব্যাখ্যা করা হলো।
ডেকোরেটরের উদাহরণ
ধরা যাক, আমরা একটি ফাংশন তৈরি করবো যা প্রতিটি কলের আগে এবং পরে কিছু মেসেজ প্রিন্ট করবে।
১. সাধারণ ডেকোরেটর তৈরি করা
def my_decorator(func):
def wrapper():
print("Function is about to run.")
func()
print("Function has finished running.")
return wrapper
এখানে, my_decorator একটি ডেকোরেটর ফাংশন যা একটি func ফাংশন গ্রহণ করে এবং একটি wrapper ফাংশন রিটার্ন করে। wrapper ফাংশন মূল ফাংশন কলের আগে এবং পরে মেসেজ প্রিন্ট করে।
২. ডেকোরেটর ব্যবহার করা
@my_decorator
def say_hello():
print("Hello, World!")
say_hello()
আউটপুট হবে:
Function is about to run.
Hello, World!
Function has finished running.
এখানে @my_decorator ব্যবহার করে আমরা say_hello ফাংশনের উপর ডেকোরেটর প্রয়োগ করেছি, যা say_hello ফাংশনের আগে এবং পরে মেসেজ প্রিন্ট করে।
আর্গুমেন্টসহ ডেকোরেটর
ডেকোরেটর তৈরি করা যেতে পারে যা ফাংশনের আর্গুমেন্ট গ্রহণ করতে পারে। এর জন্য *args এবং **kwargs ব্যবহার করতে হবে।
def my_decorator(func):
def wrapper(*args, **kwargs):
print("Function is about to run.")
result = func(*args, **kwargs)
print("Function has finished running.")
return result
return wrapper
এখন, আমরা একটি ফাংশন ডেকোরেট করবো যাতে আর্গুমেন্ট পাঠানো যায়।
@my_decorator
def add(a, b):
return a + b
print("Result:", add(5, 3))
আউটপুট:
Function is about to run.
Function has finished running.
Result: 8
ডেকোরেটরের ব্যবহার
ডেকোরেটর ব্যবহার করে প্রোগ্রামে বিভিন্ন সুবিধা যুক্ত করা যায়। কিছু সাধারণ ব্যবহার নিচে আলোচনা করা হলো:
লগিং (Logging): ফাংশন কলের সময় লগ মেসেজ প্রিন্ট করতে।
অথেনটিকেশন: কোনো ফাংশনে অথেনটিকেশন বা অনুমোদন প্রক্রিয়া যোগ করতে।
টাইমিং (Timing): একটি ফাংশন কত সময় নিচ্ছে তা মাপতে।
টাইমিং ডেকোরেটর উদাহরণ
import time
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function took {end_time - start_time} seconds to complete.")
return result
return wrapper
@timer_decorator
def slow_function():
time.sleep(2)
print("Function is done.")
slow_function()
আউটপুট:
Function is done.
Function took 2.0001234 seconds to complete.
এখানে timer_decorator ডেকোরেটরের মাধ্যমে slow_function এর রান টাইম মাপা হয়েছে।
ডেকোরেটর চেইনিং
একাধিক ডেকোরেটর একটি ফাংশনের উপর প্রয়োগ করা যেতে পারে। এটি ডেকোরেটর চেইনিং হিসেবে পরিচিত।
def decorator1(func):
def wrapper():
print("Decorator 1")
func()
return wrapper
def decorator2(func):
def wrapper():
print("Decorator 2")
func()
return wrapper
@decorator1
@decorator2
def say_hello():
print("Hello, World!")
say_hello()
আউটপুট হবে:
Decorator 1
Decorator 2
Hello, World!
এখানে, decorator2 প্রথমে say_hello এর উপর প্রয়োগ করা হয়েছে এবং তারপর decorator1 প্রয়োগ করা হয়েছে।
সারসংক্ষেপ
ডেকোরেটর পাইথনে ফাংশনের আচরণ প্রসারিত করতে ব্যবহৃত একটি শক্তিশালী টুল। এটি নতুন ফাংশনালিটি যোগ করতে সহায়ক, যেমন লগিং, অথেনটিকেশন, টাইমিং ইত্যাদি। ডেকোরেটর কোডকে আরও মডুলার, পরিষ্কার এবং পুনঃব্যবহারযোগ্য করে।
Context Manager হলো Python-এর একটি গুরুত্বপূর্ণ কনসেপ্ট, যা রিসোর্স পরিচালনা, যেমন ফাইল অপারেশন বা ডেটাবেস কানেকশন, আরো সহজ ও নিরাপদ করে তোলে। Context Manager ব্যবহার করলে রিসোর্সগুলো স্বয়ংক্রিয়ভাবে মুক্ত বা বন্ধ হয়ে যায়, এমনকি যদি কোডে কোনো এক্সসেপশন (ত্রুটি) থাকে তবুও।
Context Manager-এর কাজ
Context Manager সাধারণত with স্টেটমেন্টের মাধ্যমে ব্যবহার করা হয়। এটি দুইটি গুরুত্বপূর্ণ মেথড ব্যবহার করে কাজ করে:
__enter__(): রিসোর্সটি ইন্সট্যান্স তৈরি করার জন্য।__exit__(): রিসোর্সটি বন্ধ বা মুক্ত করার জন্য।
উদাহরণ: ফাইল পরিচালনায় Context Manager
ফাইল পরিচালনায় Context Manager অত্যন্ত জনপ্রিয়। নিচে একটি উদাহরণ দেয়া হলো যেখানে with স্টেটমেন্টের মাধ্যমে একটি ফাইল খোলা হয়েছে, এবং কাজ শেষে ফাইলটি স্বয়ংক্রিয়ভাবে বন্ধ হয়ে গেছে।
with open('example.txt', 'w') as file:
file.write("Hello, World!")
# এখানে ফাইলটি স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে, এমনকি যদি এক্সসেপশন থাকে।
এখানে open() ফাংশন __enter__ এবং __exit__ মেথড ব্যবহার করে কাজ করে, যা ফাইলটি স্বয়ংক্রিয়ভাবে বন্ধ করে দেয়।
কাস্টম Context Manager তৈরি
Python-এ কাস্টম Context Manager তৈরি করতে __enter__() এবং __exit__() মেথডসহ একটি ক্লাস তৈরি করতে হবে।
উদাহরণ
class MyContextManager:
def __enter__(self):
print("Entering the context")
return "Hello from context!"
def __exit__(self, exc_type, exc_value, traceback):
print("Exiting the context")
# কনটেক্সট ম্যানেজার ব্যবহার
with MyContextManager() as message:
print(message)
আউটপুট:
Entering the context
Hello from context!
Exiting the context
এখানে:
__enter__()মেথডে রিসোর্স প্রস্তুত করা হয়েছে, এবং এটিreturnদিয়ে একটি মান প্রদান করেছে।__exit__()মেথডে রিসোর্সটি বন্ধ বা মুক্ত করা হয়েছে।
Contextlib লাইব্রেরি দিয়ে Context Manager তৈরি
Python-এর contextlib লাইব্রেরি contextmanager ডেকোরেটর প্রদান করে, যা দিয়ে সহজে Context Manager তৈরি করা যায়।
from contextlib import contextmanager
@contextmanager
def my_context():
print("Entering the context")
yield "Hello from context!"
print("Exiting the context")
# Context Manager ব্যবহার
with my_context() as message:
print(message)
আউটপুট:
Entering the context
Hello from context!
Exiting the context
এখানে:
@contextmanagerডেকোরেটর একটি সাধারণ ফাংশনকে Context Manager এ পরিণত করেছে।yieldফাংশনটি__enter__()এবং__exit__()এর মতো কাজ করে।
একটি উদাহরণ: ডেটাবেস কানেকশন ব্যবস্থাপনা
from contextlib import contextmanager
@contextmanager
def connect_to_database():
print("Connecting to the database")
yield "Database connection established"
print("Closing the database connection")
# Context Manager ব্যবহার
with connect_to_database() as connection:
print(connection)
আউটপুট:
Connecting to the database
Database connection established
Closing the database connection
এই উদাহরণে, connect_to_database ফাংশনটি একটি Context Manager তৈরি করেছে যা ডেটাবেস কানেকশন খুলে এবং কাজ শেষে বন্ধ করে।
উপসংহার
Python-এ Context Manager রিসোর্স ব্যবস্থাপনার একটি চমৎকার উপায়। with স্টেটমেন্টের মাধ্যমে সহজে Context Manager ব্যবহার করা যায়। এটি স্বয়ংক্রিয়ভাবে রিসোর্স মুক্ত করে দেয়, যা কোডের স্থিতিশীলতা ও নিরাপত্তা বৃদ্ধি করে।
Read more