फं

फंक्शन में Python

{one: "1 अभ्यास", other: "%{count} अभ्यास"}

फंक्शन के बारे में

एक function व्यवस्थित और दोबारा इस्तेमाल किए जा सकने वाले कोड का एक ब्लॉक होता है, जिसका इस्तेमाल किसी खास काम को करने के लिए किया जाता है। Functions आपके एप्लिकेशन को बेहतर मॉड्यूलरता देते हैं और कोड को बड़े पैमाने पर दोबारा इस्तेमाल करने की सुविधा देते हैं। Python में भी, दूसरी प्रोग्रामिंग भाषाओं की तरह, अंतर्निहित फंक्शन (print, map, आदि) होते हैं, जो तुरंत इस्तेमाल के लिए तैयार रहते हैं। आप अपने खुद के फंक्शन भी बना सकते हैं। इन्हें user-defined functions कहा जाता है। फंक्शन कंसोल पर संदेश प्रिंट करने जैसा आसान काम भी कर सकते हैं, और बहुत जटिल भी हो सकते हैं।

किसी फंक्शन के अंदर का कोड चलाने के लिए आपको उस फंक्शन को कॉल करना होता है। यह फंक्शन के नाम के बाद ब्रैकेट [()] लगाकर किया जाता है। डेटा, जिसे arguments कहा जाता है, ब्रैकेट के अंदर रखकर फंक्शन को भेजा जा सकता है। किसी फंक्शन की परिभाषा में शून्य या उससे अधिक parameters हो सकते हैं। पैरामीटर तय करते हैं कि फंक्शन कौन-कौन से आर्गुमेंट स्वीकार करेगा। एक पैरामीटर तय करता है कि किस प्रकार का आर्गुमेंट भेजा जाना है। आर्गुमेंट वह असली वैल्यू होती है जो फंक्शन को कॉल करते समय भेजी जाती है। पैरामीटर को भेजे गए आर्गुमेंट के हिसाब से फंक्शन अलग-अलग काम कर सकते हैं।

एक फंक्शन return कीवर्ड की मदद से एक वैल्यू भी लौटा सकता है। फंक्शन जो वैल्यू लौटाता है, उसे return value कहा जाता है। रिटर्न वैल्यू फंक्शन को कॉल करने वाले को लौटा दी जाती है।

बनाना

Python में फंक्शन def कीवर्ड से बनाए जाते हैं। फंक्शन की परिभाषा के बाद फंक्शन का नाम और ब्रैकेट [()] लिखे जाते हैं। ब्रैकेट के अंदर पैरामीटर लिखे जाते हैं, जिन्हें कॉमा से अलग किया जाता है। बंद ब्रैकेट के बाद कोलन (:) फंक्शन सिग्नेचर को फंक्शन के अंदर के कोड से अलग करता है।

फंक्शन के अंदर का कोड एक कोड ब्लॉक होता है, जो फंक्शन को कॉल करने पर चलता है। फंक्शन के अंदर के कोड को इंडेंट किया जाता है। इंडेंटेशन ज़रूरी है, क्योंकि Python इसी के आधार पर पहचानता है कि कोड का वह ब्लॉक कहाँ खत्म होता है। return कीवर्ड का इस्तेमाल करके फंक्शन से एक वैल्यू लौटाई जा सकती है, जिसे फिर फंक्शन को कॉल करने वाला इस्तेमाल कर सकता है।

def function_name(parameter1, parameter2, ...):
    # function body
    return parameter1 + parameter2

हम बिना किसी पैरामीटर या रिटर्न वैल्यू के भी फंक्शन बना सकते हैं।

def function_name():
    # function body
    pass

ध्यान दीजिए कि फंक्शन के अंदर कोड होना ज़रूरी है, भले ही वह कोड कुछ न करे। वरना प्रोग्राम चलाने की कोशिश करने पर इंडेंटेशन एरर मिलेगी:

>>> def my_bodyless_func():
...      

File ~/temp.py:1
    
    ^
IndentationError: expected an indented block

फंक्शन को कॉल करना

किसी फंक्शन को कॉल करने के लिए फंक्शन का नाम लिखिए और उसके बाद ब्रैकेट [()] लगाइए। फंक्शन को भेजे जाने वाले पैरामीटर ब्रैकेट के अंदर रखे जाते हैं और कॉमा से अलग किए जाते हैं।

इस फंक्शन को देखिए:

def greet():
    print("Hello")

ऊपर दिए गए फंक्शन को इस तरीके से कॉल किया जा सकता है:

>>> greet()
Hello

पैरामीटर और उनके आर्गुमेंट

आर्गुमेंट वे वैल्यू हैं जो फंक्शन को कॉल करते समय भेजी जाती हैं। ये किसी भी डेटा टाइप की हो सकती हैं, जिनमें दूसरे फंक्शन या क्लास भी शामिल हैं।

चलिए एक फंक्शन add बनाते हैं जो दो संख्याएँ जोड़ता है:

def add(first, second):
    print(first + second)

पैरामीटर first और second तय करते हैं कि add फंक्शन कौन-कौन से आर्गुमेंट स्वीकार करेगा। (ध्यान दीजिए कि parameter और argument शब्द अक्सर एक-दूसरे की जगह इस्तेमाल किए जाते हैं, हालाँकि यह सही नहीं है।) फंक्शन को कॉल करने पर आर्गुमेंट उसे भेज दिए जाते हैं। हमें दोनों पैरामीटर के लिए आर्गुमेंट भेजने होते हैं, वरना TypeError आ जाएगी।

>>> add(2, 3)
5

# Function can be called multiple times, with different parameters
>>> add(4, 3)
7
>>> add(5, 6)
11

# Passing an incorrect number of parameters will raise a `TypeError`
>>> add(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() missing 1 required positional argument: 'second'

>>> add(2, 3, 4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() takes 2 positional arguments but 3 were given

रिटर्न वैल्यू

रिटर्न वैल्यू वह वैल्यू है जो फंक्शन को कॉल करने वाले को लौटाई जाती है। एक return value किसी भी डेटा टाइप की हो सकती है, जिनमें दूसरे फंक्शन या क्लास भी शामिल हैं। फंक्शन को कॉल करने वाला इसका इस्तेमाल आगे के और काम करने के लिए कर सकता है। अगर कोई फंक्शन साफ़-साफ़ कोई return value तय नहीं करता, तो Python इंटरप्रेटर None वैल्यू लौटा देता है।

चलिए एक फंक्शन add बनाते हैं:

def add(first, second):
    return first + second

हम रिटर्न वैल्यू को एक वेरिएबल में संग्रहीत करके उसे प्रिंट कर सकते हैं:

>>> result = add(2, 3)
>>> print(result)
5
# Type of result is `int`
>>> type(result)
<class 'int'>

# We can also perform operations on the return value
>>> result * 2
10

# A function without an explicit return value will return `None`
>>> def log(message):
    print(message)

# Hello is printed because of print(message), but return value is `None`
>>> return_value = log("Hello")
Hello
>>> return_value
None

return का इस्तेमाल फंक्शन से तुरंत बाहर निकल देता है और वैल्यू कॉल करने वाले को लौटा देता है।

>>> def show(first, second):
    print(first)
    return first
    print(second)

# second never gets printed, because the function exits after the return statement
>>> show(1, 2)
1

मॉड्यूलरता

जटिल प्रोग्राम को छोटे-छोटे हिस्सों में बाँटा जा सकता है। अलग-अलग खास काम करने के लिए अलग-अलग फंक्शन इस्तेमाल किए जा सकते हैं।

मान लीजिए किसी प्रोग्राम को ये काम करने हैं:

  • वृत्त (circle) का क्षेत्रफल निकालना
  • आयत (rectangle) का क्षेत्रफल निकालना
  • त्रिभुज (triangle) का क्षेत्रफल निकालना

हम प्रोग्राम को छोटे-छोटे हिस्सों में बाँट सकते हैं।

def circle_area(radius):
    return 3.14 * radius * radius

def rectangle_area(length, breadth):
    return length * breadth

def triangle_area(base, height):
    return 0.5 * base * height

अब हम इन फंक्शन को जिस क्रम में चाहें, उस क्रम में कॉल कर सकते हैं।

>>> circle_area(2)
12.56
>>> triangle_area(2, 3)
3.0
>>> rectangle_area(2, 3)
6
>>> rectangle_area(1, 2) + circle_area(2) + triangle_area(1, 2)
15.56

वेरिएबल का स्कोप

अगर कोई वेरिएबल (या नाम) किसी फंक्शन के अंदर बनाया जाता है, तो वह सिर्फ फंक्शन के स्कोप (या लोकल नेमस्पेस) के अंदर ही इस्तेमाल किया जा सकता है, भले ही फंक्शन के स्कोप के बाहर उसी नाम का वेरिएबल मौजूद हो।

किसी फंक्शन के बाहर मॉड्यूल लेवल पर बनाए गए वेरिएबल ग्लोबल नेमस्पेस में माने जाते हैं। किसी फंक्शन के बाहर, लेकिन किसी बाहरी फंक्शन या क्लास के अंदर बनाए गए वेरिएबल नॉनलोकल नेमस्पेस में होते हैं।

प्रोग्राम चलने के दौरान वेरिएबल के नाम तय करने के लिए Python LEGB Rule का इस्तेमाल करता है (Local, Enclosing, Global, Built-in):

  1. लोकल (या फंक्शन) नेमस्पेस में देखा जाता है।
  2. अगर नाम लोकल में न मिले, तो एनक्लोज़िंग (या नॉनलोकल) नेमस्पेस में देखा जाता है।
  3. अगर नाम नॉनलोकल/एनक्लोज़िंग में न मिले, तो ग्लोबल नेमस्पेस (मॉड्यूल लेवल) में देखा जाता है।
  4. अगर नाम ग्लोबल में न मिले, तो बिल्ट-इन (प्रोग्राम या पूरे python के) नेमस्पेस में देखा जाता है।

अगर नाम फिर भी न मिले, तो Python NameError exception पैदा कर देगा।

# Global namespace.
general_favorite = "apples"


def alices_favorite():
   # Local namespace.  
   favorite = "cherries"
   
   # This works because Python will eventually find general_favorite in the global namespace.
   # Python will find 'print' in the built-in namespace.
   print(f'Alice has always liked {favorite}, but most people like {general_favorite}.')

   
def our_favorite_fruits():
    # Enclosing or nonlocal namespace.
    yours = "peaches"
    
    def my_favorite():
        # Local namespace.
        mine = "pears"
        
        # This works because Python will eventually find 'yours' in the enclosing/nonlocal namespace.
        print(f'My favorite is {mine}, but you like {yours} instead.')
        
        # This works because Python will eventually find 'general_favorite' in the global namespace.
        print(f'Everyone seems to like {general_favorite}')
    
    # This function is in the local namespace of the 'our_favorite_fruits' function.  
    my_favorite()

    
# This will raise NameError: name 'favorite' is not defined, because the variable favorite is local to alices_favorite.
print(favorite)

अगर हम चाहते हैं कि कोई वेरिएबल नाम फंक्शन के लोकल स्कोप के बाहर भी इस्तेमाल हो सके (या फंक्शन के स्कोप के बाहर बनाए गए किसी वेरिएबल को बदला जा सके), तो हमें global या nonlocal कीवर्ड में से किसी एक का इस्तेमाल करना होता है।

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

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

फर्स्ट-क्लास ऑब्जेक्ट के रूप में फंक्शन

Python में फंक्शन को वेरिएबल में असाइन किया जा सकता है और दूसरे फंक्शन को आर्गुमेंट के तौर पर भेजा जा सकता है। इन्हें रिटर्न वैल्यू के तौर पर भी इस्तेमाल किया जा सकता है। फंक्शन को किसी सीक्वेंस (list, tuple आदि) में या किसी dict में वैल्यू के तौर पर भी रखा जा सकता है। फंक्शन का इस्तेमाल वहीं किया जा सकता है जहाँ किसी और ऑब्जेक्ट का किया जा सकता है। इसकी वजह यह है कि फंक्शन फर्स्ट-क्लास ऑब्जेक्ट होते हैं। इसी वजह से इनमें खास एट्रिब्यूट होते हैं, और ये अपने खुद के कस्टम एट्रिब्यूट को पढ़ना और लिखना भी तय कर सकते हैं।

# print is a function

# A function can be assigned to a variable.
>>> function_as_variable = print
>>> function_as_variable("Hello")
Hello
>>> type(fake_print)
<class 'builtin_function_or_method'>

# Functions can be passed as an argument to another function.
>>> def check_print(func):
    func("Hello")
>>> check_print(print)
Hello

# Function can be used as an item in a sequence.
>>> my_list = [print, "Hello"]
>>> my_list[0]("Hello")
Hello

# Functions can be used as a value in a dictionary.
>>> my_dict = {"key": print}
>>> my_dict["key"]("Hello")
Hello

# Functions can be returned from a function.
>>> def return_func():
    return print
>>> return_func()("Hello")
Hello

फंक्शन दूसरे फंक्शन के अंदर भी नेस्टेड हो सकते हैं।

def outer():
    num = 10
    
    # This is a nested, or "inner" function.
    def inner():
        print(num)
    
    # Outer function calling inner function
    inner()

अंदर वाला फंक्शन बाहरी फंक्शन में बनाए गए वेरिएबल num तक पहुँच सकता है।

>>> outer()
10

खास एट्रिब्यूट

Python में फंक्शन के कुछ खास एट्रिब्यूट होते हैं। इनमें से कुछ ये हैं:

  • __name__: फंक्शन का नाम
  • __doc__: फंक्शन की डॉक्युमेंटेशन स्ट्रिंग
  • __module__: जिस मॉड्यूल में फंक्शन बनाया गया है
  • __globals__: फंक्शन के ग्लोबल वेरिएबल की डिक्शनरी
  • __code__: फंक्शन के निर्देशों वाला कोड ऑब्जेक्ट
>>> def add(first, second):
      return first + second

# Function name
>>> print.__name__
'print'
>>> len.__name__
'len'
>>> add.__name__
'add'

# Function documentation
>>> abs.__doc__
'Return the absolute value of the argument.'

# Module
>>> len.__module__
'builtins'
>>> add.__module__
'__main__'

फंक्शन एट्रिब्यूट की पूरी सूची Python DataModel पर देखी जा सकती है।

GitHub के ज़रिए संपादित करें यह लिंक नई विंडो या टैब में खुलता है।