मुख्य सामग्री पर जाएँ

Python डेकोरेटर का उपयोग कैसे करें (फ़ंक्शन और क्लास-आधारित उदाहरणों सहित)

हैंड्स-ऑन उदाहरणों के साथ Python डेकोरेटर सीखें। क्लोज़र, फ़ंक्शन और क्लास-आधारित डेकोरेटर समझें, और पुन: प्रयोज्य, सुघड़ कोड लिखें।
· 11 मि॰ पढ़ें

AI के साथ खोजें

Python में डेकोरेटर एक शक्तिशाली और सजीला फीचर है, जो आपको फ़ंक्शनों और मेथड्स के व्यवहार को उनके कोड को बदले बिना संशोधित या विस्तारित करने देता है।

डेकोरेटर Python का एक डिज़ाइन पैटर्न है जो किसी मौजूदा ऑब्जेक्ट में उसकी संरचना बदले बिना नई कार्यक्षमता जोड़ने की अनुमति देता है। डेकोरेटर आमतौर पर फ़ंक्शनों पर लगाए जाते हैं और फ़ंक्शनों के व्यवहार को बेहतर करने या संशोधित करने में महत्वपूर्ण भूमिका निभाते हैं। परंपरागत रूप से, डेकोरेटर उस फ़ंक्शन की परिभाषा से पहले लगाए जाते हैं जिसे आप डेकोरेट करना चाहते हैं। इस ट्यूटोरियल में, हम बताएंगे कि Python फ़ंक्शनों में डेकोरेटर का प्रभावी उपयोग कैसे करें।

संक्षेप में

  • डेकोरेटर आपको मूल कोड बदले बिना फ़ंक्शन के व्यवहार को संशोधित या विस्तारित करने देते हैं
  • डेकोरेटर साफ़-सुथरे तरीके से लगाने के लिए @decorator_name सिंटैक्स का उपयोग करें
  • डेकोरेटर लिखते समय फ़ंक्शन मेटाडेटा को सुरक्षित रखने के लिए हमेशा functools.wraps का इस्तेमाल करें
  • क्लास-आधारित डेकोरेटर फ़ंक्शन कॉल्स के बीच स्टेटफुल व्यवहार संभव बनाते हैं
  • आम उपयोग मामलों में कैशिंग (@lru_cache), लॉगिंग, ऑथेंटिकेशन, और इनपुट वैलिडेशन शामिल हैं

First-Class ऑब्जेक्ट के रूप में फ़ंक्शन

Python में फ़ंक्शंस फर्स्ट-क्लास सिटिज़न्स हैं। यानी इन्हें आर्ग्युमेंट के रूप में पास किया जा सकता है, फ़ंक्शन से लौटाया जा सकता है, संशोधित किया जा सकता है और किसी वेरिएबल को असाइन किया जा सकता है। यह गुण महत्वपूर्ण है क्योंकि इससे फ़ंक्शंस को Python में किसी भी अन्य ऑब्जेक्ट की तरह ट्रीट किया जा सकता है, जिससे प्रोग्रामिंग में अधिक लचीलापन मिलता है।

इस ट्यूटोरियल के सभी उदाहरण कोड आप स्वयं आसानी से चलाना चाहते हैं तो आप मुफ़्त में एक DataLab वर्कबुक बनाएँ जिसमें Python पहले से इंस्टॉल है और सभी कोड सैंपल शामिल हैं। डेकोरेटर पर और अभ्यास के लिए यह DataCamp का हैंड्स-ऑन अभ्यास देखें।

फ़ंक्शनों को वेरिएबल्स को असाइन करना

शुरुआत के लिए हम एक ऐसा फ़ंक्शन बनाएँगे जो हर बार कॉल होने पर किसी संख्या में 1 जोड़ दे। फिर हम इस फ़ंक्शन को एक वेरिएबल को असाइन करेंगे और इसी वेरिएबल से फ़ंक्शन को कॉल करेंगे।

def plus_one(number):
    return number + 1

add_one = plus_one
add_one(5)
6

अन्य फ़ंक्शनों के अंदर फ़ंक्शन परिभाषित करना 

Python में फ़ंक्शनों के अंदर फ़ंक्शन परिभाषित करना एक शक्तिशाली सुविधा है—और डेकोरेटर बनाने के लिए आवश्यक भी। अब एक और मुख्य विचार देखें: फ़ंक्शनों को आर्ग्युमेंट के रूप में पास करना। यह हमें डेकोरेटर लिखने के एक कदम और करीब ले जाएगा।

def plus_one(number):
    def add_one(number):
        return number + 1


    result = add_one(number)
    return result
plus_one(4)
5

अन्य फ़ंक्शनों को फ़ंक्शन आर्ग्युमेंट के रूप में पास करना

फ़ंक्शंस को अन्य फ़ंक्शनों के पैरामीटर्स के रूप में भी पास किया जा सकता है। नीचे उसका उदाहरण देखते हैं।

def plus_one(number):
    return number + 1

def function_call(function):
    number_to_add = 5
    return function(number_to_add)

function_call(plus_one)
6

दूसरे फ़ंक्शन लौटाने वाले फ़ंक्शन

कोई फ़ंक्शन एक और फ़ंक्शन भी बना सकता है। नीचे एक उदाहरण से यह दिखाते हैं।

def hello_function():
    def say_hi():
        return "Hi"
    return say_hi
hello = hello_function()
hello()
'Hi'

इनर फ़ंक्शंस और क्लोज़र

Python किसी nested फ़ंक्शन को enclosing फ़ंक्शन के बाहरी स्कोप तक पहुँचने की अनुमति देता है। डेकोरेटर में यही एक महत्वपूर्ण अवधारणा है, जिसे क्लोज़र कहा जाता है।

Python में क्लोज़र वह फ़ंक्शन है जो उस वातावरण को याद रखता है जिसमें वह बनाया गया था, भले ही वह वातावरण अब सक्रिय न हो। यानी कोई nested फ़ंक्शन अपने enclosing स्कोप से वेरिएबल्स को “close over” कर सकता है और उनका उपयोग जारी रख सकता है।

डेकोरेटर समझने के लिए क्लोज़र आवश्यक हैं, क्योंकि डेकोरेटर इस क्षमता पर निर्भर करते हैं कि wrapper फ़ंक्शन (जो डेकोरेटर के अंदर होता है) enclosing डेकोरेटर फ़ंक्शन की स्टेट को एक्सेस और संशोधित कर सके।

क्लोज़र का उदाहरण:

def outer_function(message):
    def inner_function():
        print(f"Message from closure: {message}")
    return inner_function

closure_function = outer_function("Hello, closures!")
closure_function()
# Output: Message from closure: Hello, closures!

इस उदाहरण में:

  • inner_function एक क्लोज़र है क्योंकि यह अपने enclosing स्कोप (outer_function) के वेरिएबल message को एक्सेस करता है।
  • भले ही outer_function का निष्पादन समाप्त हो चुका है, inner_function को message तक पहुँच बनी रहती है।

जब आप कोई डेकोरेटर बनाते हैं, तो wrapper फ़ंक्शन (जो डेकोरेटर के अंदर होता है) एक क्लोज़र होता है। यह डेकोरेट किए जाने वाले फ़ंक्शन और डेकोरेटर फ़ंक्शन में परिभाषित किसी भी अतिरिक्त स्टेट या आर्ग्युमेंट्स तक पहुँच बनाए रखता है। उदाहरण के लिए:

def simple_decorator(func):
    def wrapper():
        print("Before the function call")
        func()
        print("After the function call")
    return wrapper

@simple_decorator
def greet():
    print("Hello!")

greet()
# Output:
# Before the function call
# Hello!
# After the function call

यहाँ wrapper एक क्लोज़र है जो greet फ़ंक्शन को याद रखता है और उसके निष्पादन से पहले और बाद में व्यवहार जोड़ता है।

अपना पहला डेकोरेटर बनाना

अब जब आप क्लोज़र—यानी किसी फ़ंक्शन की अपने enclosing स्कोप के वेरिएबल्स को याद रखने की क्षमता—समझ चुके हैं, तो हम अपना पहला वास्तविक डेकोरेटर बनाने के लिए तैयार हैं। पर्दे के पीछे डेकोरेटर को काम करवाने में क्लोज़र ही गुप्त मसाला है।

आइए एक सरल डेकोरेटर बनाते हैं जो किसी वाक्य को uppercase में बदल देगा। यह हम एक enclosed फ़ंक्शन के अंदर wrapper परिभाषित करके करते हैं। जैसा कि आप देख सकते हैं, यह पहले बनाए गए “फ़ंक्शन के अंदर फ़ंक्शन” जैसा ही है।

def uppercase_decorator(function):
    def wrapper():
        func = function()
        make_uppercase = func.upper()
        return make_uppercase

    return wrapper

क्योंकि हमारा डेकोरेटर एक फ़ंक्शन को आर्ग्युमेंट के रूप में लेता है, हम एक नया फ़ंक्शन परिभाषित करेंगे और उसे डेकोरेटर को पास करेंगे। पहले सीखी हुई बात के अनुसार हम फ़ंक्शन को किसी वेरिएबल में असाइन कर सकते हैं। हम उसी तरकीब का उपयोग करके अपने डेकोरेटर फ़ंक्शन को कॉल करेंगे।

def say_hi():
    return 'hello there'

decorate = uppercase_decorator(say_hi)
decorate()
'HELLO THERE'

@ सिंटैक्स का उपयोग

हालाँकि, Python डेकोरेटर लगाने का एक और भी आसान तरीका देता है। हमें जिस फ़ंक्शन को डेकोरेट करना है, उसके ऊपर बस @ प्रतीक का उपयोग करना होता है। नीचे इसे व्यवहार में दिखाते हैं।

@uppercase_decorator
def say_hi():
    return 'hello there'

say_hi()
'HELLO THERE'

एक ही फ़ंक्शन पर कई डेकोरेटर लगाना

जब आप एक डेकोरेटर के लिए @ सिंटैक्स के साथ सहज हो जाएँ, तो आप एक कदम आगे बढ़कर उसी फ़ंक्शन पर कई डेकोरेटर स्टैक कर सकते हैं। बस याद रखें: क्रम मायने रखता है!

नीचे हम एक और डेकोरेटर परिभाषित करेंगे जो वाक्य को सूची में बाँट देगा। फिर हम uppercase_decorator और split_string डेकोरेटर को एक ही फ़ंक्शन पर लागू करेंगे।

import functools
def split_string(function):
    @functools.wraps(function)
    def wrapper():
        func = function()
        splitted_string = func.split()
        return splitted_string

    return wrapper 
@split_string
@uppercase_decorator
def say_hi():
    return 'hello there'
say_hi()
['HELLO', 'THERE']

ऊपर के आउटपुट से दिखता है कि डेकोरेटर नीचे से ऊपर की दिशा में लगाए जाते हैं। अगर हमने क्रम बदल दिया होता, तो हमें त्रुटि मिलती क्योंकि list में upper एट्रिब्यूट नहीं होता। पहले वाक्य uppercase में बदला गया और फिर सूची में बाँटा गया।

नोट: कई डेकोरेटर स्टैक करते समय, यह आम प्रचलन है कि functools.wraps का उपयोग करें ताकि मूल फ़ंक्शन का मेटाडेटा पूरे स्टैकिंग प्रोसेस में सुरक्षित रहे। यह डेकोरेटेड फ़ंक्शन की properties को समझने और डिबगिंग में स्पष्टता और सुसंगतता बनाए रखने में मदद करता है।

डेकोरेटर में आर्ग्युमेंट स्वीकार करना

अब तक हमने ऐसे डेकोरेटर देखे जो केवल किसी फ़ंक्शन को wrap करते हैं। लेकिन अगर आप खुद डेकोरेटर को कॉन्फ़िगर करना चाहें—जैसे इसमें पैरामीटर्स पास करना? यहीं पर डेकोरेटर फ़ैक्टरी काम आती है।

def decorator_with_arguments(function):
    def wrapper_accepting_arguments(arg1, arg2):
        print("My arguments are: {0}, {1}".format(arg1,arg2))
        function(arg1, arg2)
    return wrapper_accepting_arguments


@decorator_with_arguments
def cities(city_one, city_two):
    print("Cities I love are {0} and {1}".format(city_one, city_two))

cities("Nairobi", "Accra")

My arguments are: Nairobi, Accra Cities I love are Nairobi and Accra

नोट: यह सुनिश्चित करना आवश्यक है कि डेकोरेटर में आर्ग्युमेंट्स की संख्या (इस उदाहरण में
arg1, arg2) wrapper किए गए फ़ंक्शन (इस उदाहरण में cities) के आर्ग्युमेंट्स की संख्या से मेल खाएँ। यह तालमेल त्रुटियों से बचने और डेकोरेटर-विद-आर्ग्युमेंट्स को सही तरह कार्य करने के लिए महत्वपूर्ण है।

*args और **kwargs के साथ जनरल-पर्पज़ डेकोरेटर

ऐसा general purpose डेकोरेटर परिभाषित करने के लिए जिसे किसी भी फ़ंक्शन पर लगाया जा सके, हम *args और **kwargs का उपयोग करते हैं। *args और **kwargs सभी positional और keyword आर्ग्युमेंट्स को एकत्र करते हैं और उन्हें क्रमशः *args और **kwargs वेरिएबल्स में रखते हैं। इनके इस्तेमाल से हम जितने चाहें उतने आर्ग्युमेंट्स फ़ंक्शन कॉल्स के दौरान पास कर सकते हैं।

def a_decorator_passing_arbitrary_arguments(function_to_decorate):
    def a_wrapper_accepting_arbitrary_arguments(*args,**kwargs):
        print('The positional arguments are', args)
        print('The keyword arguments are', kwargs)
        function_to_decorate(*args)
    return a_wrapper_accepting_arbitrary_arguments

@a_decorator_passing_arbitrary_arguments
def function_with_no_argument():
    print("No arguments here.")

function_with_no_argument()
The positional arguments are ()
The keyword arguments are {}
No arguments here.

आइए देखें positional आर्ग्युमेंट्स के साथ हम इस डेकोरेटर का उपयोग कैसे करेंगे।

@a_decorator_passing_arbitrary_arguments
def function_with_arguments(a, b, c):
    print(a, b, c)

function_with_arguments(1,2,3)
The positional arguments are (1, 2, 3)
The keyword arguments are {}
1 2 3

यहाँ देखें कि किसी डेकोरेटेड फ़ंक्शन को keyword आर्ग्युमेंट्स कैसे पास कर सकते हैं:

@a_decorator_passing_arbitrary_arguments
def function_with_keyword_arguments():
    print("This has shown keyword arguments")

function_with_keyword_arguments(first_name="Derrick", last_name="Mwiti")
The positional arguments are ()
The keyword arguments are {'first_name': 'Derrick', 'last_name': 'Mwiti'}
This has shown keyword arguments

नोट: डेकोरेटर में **kwargs के उपयोग से वह keyword आर्ग्युमेंट्स को संभाल सकता है। यह general-purpose डेकोरेटर को बहुउद्देशीय बनाता है और फ़ंक्शन कॉल्स के दौरान विभिन्न प्रकार के आर्ग्युमेंट्स को संभालने में सक्षम बनाता है।

डेकोरेटर को आर्ग्युमेंट्स पास करना

अब देखते हैं कि हम आर्ग्युमेंट्स सीधे डेकोरेटर को कैसे पास करें। इसे पाने के लिए, हम एक डेकोरेटर मेकर परिभाषित करते हैं जो आर्ग्युमेंट्स लेता है, फिर उसके अंदर एक डेकोरेटर परिभाषित करते हैं। उसके बाद, पहले की तरह डेकोरेटर के अंदर एक wrapper फ़ंक्शन परिभाषित करते हैं।

def decorator_maker_with_arguments(decorator_arg1, decorator_arg2, decorator_arg3):
    def decorator(func):
        def wrapper(function_arg1, function_arg2, function_arg3) :
            "This is the wrapper function"
            print("The wrapper can access all the variables\n"
                  "\t- from the decorator maker: {0} {1} {2}\n"
                  "\t- from the function call: {3} {4} {5}\n"
                  "and pass them to the decorated function"
                  .format(decorator_arg1, decorator_arg2,decorator_arg3,
                          function_arg1, function_arg2,function_arg3))
            return func(function_arg1, function_arg2,function_arg3)

        return wrapper

    return decorator

pandas = "Pandas"
@decorator_maker_with_arguments(pandas, "Numpy","Scikit-learn")
def decorated_function_with_arguments(function_arg1, function_arg2,function_arg3):
    print("This is the decorated function and it only knows about its arguments: {0}"
           " {1}" " {2}".format(function_arg1, function_arg2,function_arg3))

decorated_function_with_arguments(pandas, "Science", "Tools")
The wrapper can access all the variables
    - from the decorator maker: Pandas Numpy Scikit-learn
    - from the function call: Pandas Science Tools
and pass them to the decorated function
This is the decorated function, and it only knows about its arguments: Pandas Science Tools

डेकोरेटर की डिबगिंग

जैसा कि हमने देखा, डेकोरेटर फ़ंक्शनों को wrap करते हैं। मूल फ़ंक्शन का नाम, उसका docstring और पैरामीटर सूची—all—wrapper क्लोज़र से ढक जाते हैं: उदाहरण के लिए, जब हम decorated_function_with_arguments का मेटाडेटा एक्सेस करने की कोशिश करते हैं, तो हमें wrapper क्लोज़र का मेटाडेटा दिखेगा। डिबगिंग के समय यह एक चुनौती पेश करता है।

decorated_function_with_arguments.__name__
'wrapper'
decorated_function_with_arguments.__doc__
'This is the wrapper function'

इस चुनौती को हल करने के लिए Python functools.wraps डेकोरेटर देता है। यह डेकोरेटर अनडेकोरेटेड फ़ंक्शन से खोया हुआ मेटाडेटा डेकोरेटेड क्लोज़र में कॉपी कर देता है। आइए देखें यह कैसे किया जाता है।

import functools

def uppercase_decorator(func):
    @functools.wraps(func)
    def wrapper():
        return func().upper()
    return wrapper
@uppercase_decorator
def say_hi():
    "This will say hi"
    return 'hello there'

say_hi()
'HELLO THERE'

अब, जब हम say_hi का मेटाडेटा जाँचते हैं, तो यह सही तरह मूल फ़ंक्शन को दिखाता है—न कि wrapper को।

say_hi.__name__
'say_hi'
say_hi.__doc__
'This will say hi'

डेकोरेटर परिभाषित करते समय functools.wraps का उपयोग करना सलाहयोग्य और अच्छी प्रैक्टिस है। यह डिबगिंग में आपको काफी सिरदर्द से बचाएगा।

क्लास-आधारित डेकोरेटर

जहाँ फ़ंक्शन-आधारित डेकोरेटर आम हैं, वहीं Python में आप क्लास-आधारित डेकोरेटर भी बना सकते हैं, जो खासकर जटिल उपयोग मामलों के लिए अधिक लचीलापन और maintainability देते हैं। यदि आप Python में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में नए हैं, तो आधारभूत बातें दोहराना इस अनुभाग को बेहतर समझने में मदद करेगा। क्लास-आधारित डेकोरेटर वह क्लास है जिसमें __call__ मेथड होता है, जो उसे फ़ंक्शन जैसा व्यवहार करने देता है।

class UppercaseDecorator:
    def __init__(self, function):
        self.function = function

    def __call__(self, *args, **kwargs):
        result = self.function(*args, **kwargs)
        return result.upper()

@UppercaseDecorator
def greet():
    return "hello there"

print(greet())
# Output: HELLO THERE

यह कैसे काम करता है:

  1. __init__ मेथड डेकोरेटर को डेकोरेट किए जाने वाले फ़ंक्शन के साथ initialize करता है।
  2. __call__ मेथड तब invoke होता है जब डेकोरेटेड फ़ंक्शन कॉल किया जाता है, जिससे डेकोरेटर उसके व्यवहार को संशोधित कर सकता है।

क्लास-आधारित डेकोरेटर के फायदे:

  • स्टेटफुल डेकोरेटर: क्लास-आधारित डेकोरेटर instance वेरिएबल्स का उपयोग करके स्टेट बनाए रख सकते हैं, जबकि फ़ंक्शन-आधारित डेकोरेटर को इसके लिए क्लोज़र या ग्लोबल वेरिएबल्स चाहिए होते हैं।
  • पठनीयता: जटिल डेकोरेटर के लिए, लॉजिक को किसी क्लास में एनकैप्सुलेट करना कोड को अधिक व्यवस्थित और समझने में आसान बना सकता है।

स्टेटफुल डेकोरेटर का उदाहरण:

class CallCounter:
    def __init__(self, function):
        self.function = function
        self.count = 0

    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"Function {self.function.__name__} has been called {self.count} times.")
        return self.function(*args, **kwargs)

@CallCounter
def say_hello():
    print("Hello!")

say_hello()
say_hello()
# Output:
# Function say_hello has been called 1 times.
# Hello!
# Function say_hello has been called 2 times.
# Hello!

वास्तविक दुनिया में डेकोरेटर: कैशिंग

lru_cache डेकोरेटर Python में एक बिल्ट-इन टूल है जो महंगे फ़ंक्शन कॉल्स के परिणामों को कैश करता है। इससे दोहराए गए इनपुट्स के लिए बिना ज़रूरी गणनाओं से बचकर प्रदर्शन बेहतर होता है।

उदाहरण:

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))  # Subsequent calls with the same argument are much faster

डेकोरेटर के अन्य सामान्य उपयोग:

  • लॉगिंग: डिबगिंग या ऑडिटिंग के लिए फ़ंक्शन कॉल्स, आर्ग्युमेंट्स, और रिटर्न वैल्यूज़ को ट्रैक करें।

  • ऑथेंटिकेशन: Flask या Django जैसी वेब एप्लिकेशन्स में एक्सेस कंट्रोल लागू करें।

  • निष्पादन समय मापना: परफॉर्मेंस-क्रिटिकल कार्यों के लिए फ़ंक्शनों के execution time को मापें और बेहतर करें।

  • रीट्राय मैकेनिज़्म: असफल फ़ंक्शन कॉल्स को स्वतः फिर से आज़माएँ—नेटवर्क ऑपरेशन्स में उपयोगी।

  • इनपुट वैलिडेशन: निष्पादन से पहले फ़ंक्शन आर्ग्युमेंट्स को मान्य करें।

Python डेकोरेटर सार

डेकोरेटर किसी फ़ंक्शन, मेथड, या क्लास की कार्यक्षमता को डायनैमिक रूप से बदले बिना सबक्लास का सीधा उपयोग किए या उस फ़ंक्शन के स्रोत कोड को बदले बिना बदल देते हैं जिसे डेकोरेट किया जा रहा है। Python में डेकोरेटर का उपयोग यह भी सुनिश्चित करता है कि आपका कोड DRY (Don't Repeat Yourself) रहे। डेकोरेटर के कई उपयोग मामले हैं, जैसे:

  • Flask और Django जैसे Python फ़्रेमवर्क में ऑथराइज़ेशन
  • लॉगिंग
  • निष्पादन समय मापना
  • सिंक्रोनाइज़ेशन

Python डेकोरेटर के बारे में अधिक जानने के लिए Python की Decorator Library देखें।

FAQs

डेकोरेटर का उपयोग करते समय क्या कोई परफॉर्मेंस संबंधी बातें ध्यान में रखनी चाहिए?

हाँ, डेकोरेटर अतिरिक्त फ़ंक्शन कॉल्स जोड़ते हैं, जिससे ओवरहेड आ सकता है। जब परफॉर्मेंस महत्वपूर्ण हो, विशेषकर यदि डेकोरेटेड फ़ंक्शन बार-बार और परफॉर्मेंस-सेंसिटिव संदर्भ में कॉल हो रहा हो, तो इस ओवरहेड पर ध्यान देना ज़रूरी है।

क्या डेकोरेटर क्लास मेथड्स के साथ इस्तेमाल किए जा सकते हैं? कैसे?

हाँ, डेकोरेटर को क्लास मेथड्स पर भी वैसे ही लगाया जा सकता है जैसे सामान्य फ़ंक्शनों पर। डेकोरेटर को मेथड आर्ग्युमेंट के रूप में मिलता है और वह नया या संशोधित मेथड लौटाता है। यह आमतौर पर लॉगिंग, एक्सेस कंट्रोल या प्रीकंडीशन्स लागू करने के लिए उपयोग होता है।

लॉगिंग के लिए डेकोरेटर का उपयोग कैसे किया जा सकता है?

डेकोरेटर फ़ंक्शन कॉल्स, उनके आर्ग्युमेंट्स और रिटर्न वैल्यूज़ को रिकॉर्ड करके लॉगिंग में उपयोग किए जा सकते हैं—यानि फ़ंक्शन के निष्पादन को ऐसे कोड से wrap करें जो ये विवरण किसी लॉगिंग सिस्टम में लिखे। इससे ट्रेसिंग और डिबगिंग में मदद मिलती है।

डेकोरेटर में @ प्रतीक का क्या महत्व है?

डेकोरेटर में @ प्रतीक सिंटैक्टिक शुगर है जो किसी फ़ंक्शन पर डेकोरेटर लगाना आसान बना देता है। यह आपको फ़ंक्शन परिभाषा के ठीक ऊपर डेकोरेटर लगाने देता है, जिससे कोड अधिक साफ़ और पठनीय हो जाता है।

क्या कोई डेकोरेटर फ़ंक्शन के रिटर्न वैल्यू को बदल सकता है? यह कैसे काम करेगा?

हाँ। कोई डेकोरेटर wrapper फ़ंक्शन के अंदर return स्टेटमेंट को बदलकर फ़ंक्शन के रिटर्न वैल्यू को संशोधित कर सकता है। उदाहरण के लिए, वह आउटपुट के डेटा टाइप को बदल सकता है, उसे फ़ॉर्मैट कर सकता है, या अंतिम परिणाम लौटाने से पहले अतिरिक्त प्रोसेसिंग कर सकता है।

जब कोई nested फ़ंक्शन अपने enclosing फ़ंक्शन के वेरिएबल तक पहुँचता है, तो Python स्कोप को कैसे हैंडल करता है?

Python LEGB (Local, Enclosing, Global, Built-in) स्कोप नियम का पालन करता है। nested फ़ंक्शंस के मामले में, nested फ़ंक्शन अपने enclosing फ़ंक्शन के स्कोप के वेरिएबल्स तक पहुँच सकता है—यही क्लोज़र को संभव बनाता है, जहाँ inner फ़ंक्शन outer फ़ंक्शन के वेरिएबल्स तक उसकी समाप्ति के बाद भी पहुँच बनाए रखता है।

क्लोज़र और डेकोरेटर में क्या अंतर है?

क्लोज़र वह फ़ंक्शन है जो अपने outer स्कोप के वेरिएबल्स को याद रखता है। डेकोरेटर वह फ़ंक्शन है जो अन्य फ़ंक्शनों को enhance या wrap करने के लिए क्लोज़र का उपयोग करता है।

मुझे functools.wraps कब उपयोग करना चाहिए?

डेकोरेटर लिखते समय हमेशा functools.wraps का उपयोग करें। यह मूल फ़ंक्शन का मेटाडेटा (जैसे नाम और docstring) सुरक्षित रखता है, जो डिबगिंग और डाक्यूमेंटेशन में सहायक है।

क्या डेकोरेटर आर्ग्युमेंट्स स्वीकार कर सकते हैं?

हाँ! आप डेकोरेटर को किसी दूसरी फ़ंक्शन (डेकोरेटर फ़ैक्टरी) में लपेटकर आर्ग्युमेंट्स पास कर सकते हैं। इससे आप डेकोरेटर के व्यवहार को कस्टमाइज़ कर सकते हैं।

क्लास-आधारित डेकोरेटर का क्या लाभ है?

क्लास-आधारित डेकोरेटर आपको फ़ंक्शन कॉल्स के बीच स्टेट बनाए रखने देते हैं और जटिल लॉजिक को ऑब्जेक्ट-ओरिएंटेड तरीके से संगठित करने में मदद करते हैं।

क्या डेकोरेटर केवल फ़ंक्शनों के लिए होते हैं?

नहीं। आप डेकोरेटर को क्लासेस और मेथड्स पर भी लगा सकते हैं। Flask और Django जैसे फ़्रेमवर्क में डेकोरेटर आमतौर पर रूट्स, व्यूज़ और मॉडल्स पर उपयोग होते हैं।

विषय