📋 Table of Contents
- पायथन डेकोरेटर क्या है?
- आइए एक सरल
- ऊपर डेकोरेटर में एक सूक्ष्म बग है। सजावट के बाद,
- यदि आप अपने डेकोरेटर को कॉन्फ़िगर करना चाहते हैं तो क्या होगा? उदाहरण के लिए,
- आप एक ही फ़ंक्शन में एकाधिक डेकोरेटर लागू कर सकते हैं। वे लागू होते हैं
- कोई भी कॉल करने योग्य वस्तु डेकोरेटर हो सकती है। क्लास का उपयोग करने से आपको कॉल के बीच स्थिति मिलती है:
- कई अंतर्निर्मित डेकोरेटर के साथ पायथन जहाज जिनका आप लगातार उपयोग करेंगे:
- डेकोरेटर अधिकांश पायथन फ्रेमवर्क को शक्ति प्रदान करते हैं। यहां उत्पादन-ग्रेड पैटर्न हैं:
- भूल जाना
- पायथन डेकोरेटर एक ऐसा फ़ंक्शन है जो किसी अन्य फ़ंक्शन को इनपुट के रूप में लेता है और मूल को संशोधित किए बिना एक उन्नत संस्करण लौटाता है।
पायथन डेकोरेटर क्या है?
A पायथन डेकोरेटरएक डिज़ाइन पैटर्न है जो आपको किसी मौजूदा फ़ंक्शन में नया व्यवहार जोड़ने की सुविधा देता है – फ़ंक्शन के कोड को छुए बिना। पायथन में, फ़ंक्शंस प्रथम श्रेणी की वस्तुएं हैं: उन्हें तर्क के रूप में पारित किया जा सकता है, वेरिएबल्स को सौंपा जा सकता है, और अन्य फ़ंक्शंस से लौटाया जा सकता है। सज्जाकार इस संपत्ति का शोषण करते हैं।
|||| सिंटैक्स सिर्फ सिंटैक्टिक शुगर है। जब आप लिखते हैं:@📋कॉपी
@my_decorator
def greet(name):
return f"Hello, {name}!"
📋कॉपी
greet = my_decorator(greet)
अब उन्नत संस्करण की ओर इशारा करता है।greetआपका पहला डेकोरेटर: चरण दर चरण
आइए एक सरल
बनाएं लॉगिंग डेकोरेटरजो किसी भी फ़ंक्शन को कॉल करने से पहले और बाद में एक संदेश प्रिंट करता है।📋कॉपी
def log_calls(func):
"""Decorator that logs function entry and exit."""
def wrapper(*args, **kwargs):
print(f"→ Calling {func.__name__} with args={args}, kwargs={kwargs}")
result = func(*args, **kwargs)
print(f"← {func.__name__} returned {result!r}")
return result
return wrapper
@log_calls
def add(a, b):
return a + b
add(3, 4)
# Output:
# → Calling add with args=(3, 4), kwargs={}
# ← add returned 7
प्राप्त होता है
log_calls(मूल कार्य)funcयह एक आंतरिक- को परिभाषित करता है जो स्वीकार करता है
wrapper– तो यह किसी भी फ़ंक्शन हस्ताक्षर के साथ काम करता है*args, **kwargsरैपर मूल को - कहता है , परिणाम कैप्चर करता है, और उसे लौटाता है
funcरैपर लौटाता है – इसे कॉल करने का परिणाम नहीं log_callsfunctools.wraps ठीक करें
ऊपर डेकोरेटर में एक सूक्ष्म बग है। सजावट के बाद,
रिटर्नadd.__name__, नहीं'wrapper'. ये टूट जाता है'add', और स्टैक निशान। इसेhelp(), inspectसे ठीक करें 📋कॉपीfunctools.wraps:
import functools
def log_calls(func):
@functools.wraps(func) # ← copies __name__, __doc__, __module__, etc.
def wrapper(*args, **kwargs):
print(f"→ Calling {func.__name__}")
result = func(*args, **kwargs)
print(f"← {func.__name__} returned {result!r}")
return result
return wrapper
@log_calls
def add(a, b):
"""Add two numbers."""
return a + b
print(add.__name__) # 'add' ✅
print(add.__doc__) # 'Add two numbers.' ✅
@functools.wraps(func)तर्कों के साथ सज्जाकारयदि आप अपने डेकोरेटर को कॉन्फ़िगर करना चाहते हैं तो क्या होगा? उदाहरण के लिए,
. आपको घोंसले की एक अतिरिक्त परत की आवश्यकता है – एक@retry(times=3)डेकोरेटर फ़ैक्टरी📋कॉपी:
import functools, time
def retry(times=3, delay=1.0, exceptions=(Exception,)):
"""Retry a function up to `times` times on specified exceptions."""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
last_err = None
for attempt in range(1, times + 1):
try:
return func(*args, **kwargs)
except exceptions as e:
last_err = e
print(f" Attempt {attempt}/{times} failed: {e}")
if attempt < times:
time.sleep(delay)
raise last_err
return wrapper
return decorator
@retry(times=3, delay=0.5, exceptions=(ConnectionError,))
def fetch_data(url):
# simulate a flaky network call
raise ConnectionError("timeout")
try:
fetch_data("https://api.example.com/data")
except ConnectionError:
print("All retries exhausted.")
. इसे कॉल करें:retry() → decorator() → wrapper()रिटर्नretry(times=3), जोdecoratorलेता है और लौटता हैfuncमल्टीपल डेकोरेटर्स को स्टैक करनाwrapper.
आप एक ही फ़ंक्शन में एकाधिक डेकोरेटर लागू कर सकते हैं। वे लागू होते हैं
नीचे से ऊपर(अंतरतम प्रथम):📋कॉपी
import functools, time
def timer(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
print(f"{func.__name__} took {elapsed:.4f}s")
return result
return wrapper
def log_calls(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}")
return func(*args, **kwargs)
return wrapper
@timer # applied second (outer)
@log_calls # applied first (inner)
def process(n):
return sum(range(n))
process(1_000_000)
# Output:
# Calling process
# process took 0.0312s
. व्यवस्था मायने रखती है – बाहरी सज्जाकार आंतरिक सज्जाकार को लपेटते हैं।process = timer(log_calls(process))वर्ग-आधारित सज्जाकार
कोई भी कॉल करने योग्य वस्तु डेकोरेटर हो सकती है। क्लास का उपयोग करने से आपको कॉल के बीच स्थिति मिलती है:
📋कॉपी
import functools
class CallCounter:
"""Counts how many times a function is called."""
def __init__(self, func):
functools.update_wrapper(self, func)
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"{self.func.__name__} called {self.count} time(s)")
return self.func(*args, **kwargs)
@CallCounter
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Alice") # called 1 time(s)
say_hello("Bob") # called 2 time(s)
print(say_hello.count) # 2
कई अंतर्निर्मित डेकोरेटर के साथ पायथन जहाज जिनका आप लगातार उपयोग करेंगे:
📋कॉपी
class Temperature:
_kelvin_offset = 273.15
def __init__(self, celsius):
self._celsius = celsius
@property
def fahrenheit(self):
"""Computed attribute — no () needed when accessing."""
return self._celsius * 9/5 + 32
@fahrenheit.setter
def fahrenheit(self, value):
self._celsius = (value - 32) * 5/9
@classmethod
def from_kelvin(cls, kelvin):
"""Factory method — creates instance from Kelvin."""
return cls(kelvin - cls._kelvin_offset)
@staticmethod
def is_valid_celsius(value):
"""Utility — no access to instance or class."""
return value >= -273.15
t = Temperature(100)
print(t.fahrenheit) # 212.0 (property)
t.fahrenheit = 32 # setter
t2 = Temperature.from_kelvin(373.15) # classmethod
print(Temperature.is_valid_celsius(-300)) # False (staticmethod)
| पहला तर्क | प्रवेश | केस का प्रयोग करें | उदाहरण + वर्ग |
|---|---|---|---|
@property |
self |
परिकलित विशेषताएँ, गेटर्स/सेटर्स | केवल कक्षा |
@classmethod |
cls |
फ़ैक्टरी विधियाँ, वैकल्पिक कंस्ट्रक्टर | कोई नहीं |
@staticmethod |
न ही | उपयोगिता कार्यों को वर्ग | में नामित किया गया है वास्तविक दुनिया में उपयोग के मामले |
डेकोरेटर अधिकांश पायथन फ्रेमवर्क को शक्ति प्रदान करते हैं। यहां उत्पादन-ग्रेड पैटर्न हैं:
1. एलआरयू कैश के साथ कैशिंग
📋कॉपी
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(50)) # Instant — cached results
print(fibonacci.cache_info()) # CacheInfo(hits=48, misses=51, ...)
📋कॉपी
import functools
def require_auth(func):
"""Decorator for protected routes."""
@functools.wraps(func)
def wrapper(request, *args, **kwargs):
token = request.headers.get("Authorization", "")
if not token.startswith("Bearer "):
return {"error": "Unauthorized"}, 401
return func(request, *args, **kwargs)
return wrapper
@require_auth
def get_user_profile(request):
return {"user": "Alice", "email": "alice@example.com"}
📋कॉपी
import functools, time
from collections import defaultdict, deque
def rate_limit(calls=10, period=60):
"""Allow at most `calls` per `period` seconds per caller."""
history = defaultdict(deque)
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
now = time.time()
key = args[0] if args else "default" # use first arg as caller ID
q = history[key]
while q and now - q[0] > period:
q.popleft()
if len(q) >= calls:
raise RuntimeError(f"Rate limit exceeded: {calls} calls per {period}s")
q.append(now)
return func(*args, **kwargs)
return wrapper
return decorator
@rate_limit(calls=5, period=60)
def send_email(user_id, message):
print(f"Email sent to {user_id}: {message}")
भूल जाना
- – टूट जाता है
@functools.wraps, ट्रेसबैक, और परीक्षण उपकरणhelp()डेकोरेटर बॉडी में फ़ंक्शन को कॉल करना - इसके बजाय —
return wrapper()|||| का उपयोग नहीं कर रहा हूँ – पैरामीटर के साथ किसी भी फ़ंक्शन को तोड़ता हैreturn wrapper - परिवर्तनीय डिफ़ॉल्ट स्थिति कॉलों में साझा की गई
*args, **kwargs– क्लोजर वैरिएबल का उपयोग करें, मॉड्यूल-स्तरीय म्यूटेबल डिफ़ॉल्ट का नहीं - गुमआवरण में
- – फ़ंक्शन के रिटर्न मान को चुपचाप निगल लेता है
return result📋कॉपी🚀 अपने पायथन कौशल का स्तर बढ़ाएं
# ❌ Wrong — returns None
def broken(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs) # no return!
return wrapper
# ✅ Correct
def fixed(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs) # always return
return wrapper
जैसे फ्रेमवर्क को कैसे शक्ति प्रदान करते हैं पायथन परियोजनाओं की संरचना करना
और उन्नत पैटर्न।पर हमारी मार्गदर्शिका देखें पायथन आशुलिपि अभिव्यक्तियाँअधिक पायथोनिक कोड ट्रिक्स के लिए।अक्सर पूछे जाने वाले प्रश्नपायथन डेकोरेटर क्या है?
पायथन डेकोरेटर एक ऐसा फ़ंक्शन है जो किसी अन्य फ़ंक्शन को इनपुट के रूप में लेता है और मूल को संशोधित किए बिना एक उन्नत संस्करण लौटाता है।
वाक्यविन्यास
के लिए आशुलिपि है मुझे डेकोरेटर्स का उपयोग कब करना चाहिए?@क्रॉस-कटिंग चिंताओं के लिए डेकोरेटर का उपयोग करें: लॉगिंग, कैशिंग, ऑथ, रेट लिमिटिंग, टाइमिंग, इनपुट सत्यापन – कोई भी व्यवहार जिसे आप कोड को दोहराए बिना कई कार्यों पर लागू करना चाहते हैं।func = decorator(func).
functools.wraps क्या करता है?
यह मूल फ़ंक्शन की प्रतिलिपि बनाता है
What does functools.wraps do?
It copies the original function’s__name__, __doc__, और रैपर की अन्य विशेषताएँ, डिबगिंग, सहायता (), और परीक्षण टूल के लिए पहचान को संरक्षित करना।
क्या सज्जाकारों के पास तर्क हो सकते हैं?
हाँ। एक बाहरी फ़ैक्टरी फ़ंक्शन जोड़ें जो तर्कों को स्वीकार करता है और वास्तविक डेकोरेटर लौटाता है। पैटर्न:@retry(times=3) → retry()डेकोरेटर लौटाता है.
@staticmethod और @classmethod के बीच क्या अंतर है?
@staticmethodकोई अंतर्निहित पहला तर्क नहीं मिलता है – यह क्लास नेमस्पेस में एक सादा फ़ंक्शन है।@classmethodपहले तर्क के रूप में वर्ग (cls) प्राप्त करता है, जो फ़ैक्टरी विधियों के लिए उपयोगी है।
स्टैक्ड डेकोरेटर कैसे काम करते हैं?
नीचे से ऊपर: डेकोरेटरdefके सबसे करीब पहले लागू किया जाता है.@A @B def f()के बराबर होती हैf = A(B(f)).
🔗 Share this article
✍️ Leave a Comment