यदि फ़ंक्शन A केवल फ़ंक्शन द्वारा आवश्यक है, तो B को B के अंदर परिभाषित किया जाना चाहिए? [बन्द है]


147

सरल उदाहरण है। दो तरीके, एक दूसरे से बुलाया:

def method_a(arg):
    some_data = method_b(arg)

def method_b(arg):
    return some_data

अजगर में हम defदूसरे के अंदर की घोषणा कर सकते हैं def। तो, अगर के method_bलिए आवश्यक है और केवल कहा जाता है method_a, तो मुझे method_bअंदर घोषित करना चाहिए method_a? इस तरह :

def method_a(arg):

    def method_b(arg):
        return some_data

    some_data = method_b(arg)

या मुझे ऐसा करने से बचना चाहिए?


7
जब तक आप वास्तव में कुछ नहीं कर रहे हैं तब तक आपको दूसरे के अंदर एक फ़ंक्शन को परिभाषित करने की आवश्यकता नहीं होनी चाहिए। हालाँकि, कृपया विस्तार से बताएं कि आप क्या करने की कोशिश कर रहे हैं, इसलिए हम एक अधिक उपयोगी उत्तर प्रदान कर सकते हैं
निरीक्षक

6
क्या आपको पता है कि दूसरा उदाहरण अलग है, क्योंकि आप फोन नहीं करते हैंmethod_b ? (@inspector: आपको कड़ाई से बोलने की जरूरत है, लेकिन यह तब बहुत उपयोगी है जब आप कार्यात्मक प्रोग्रामिंग के एक बिट में, विशेष रूप से बंद हो जाते हैं)।

3
@delnan: मुझे लगता है कि आपका मतलब था "आपको ज़रूरत नहीं है, सख्ती से बोलने की, लेकिन ..."
Martineau

4
आंतरिक कार्यों के उपयोग मामलों को संक्षेप में लिंक में संक्षेप में प्रस्तुत किया गया है: https://realpython.com/blog/python/inner-functions-what-are-they-good-for/ । यदि आपका उपयोग किसी भी मामले में फिट नहीं है, तो बेहतर है कि इससे बचें।

1
शानदार सवाल लेकिन ऐसा कोई वास्तविक उत्तर नहीं है जैसा ...
Mayou36

जवाबों:


136
>>> def sum(x, y):
...     def do_it():
...             return x + y
...     return do_it
... 
>>> a = sum(1, 3)
>>> a
<function do_it at 0xb772b304>
>>> a()
4

क्या यह वही है जिसकी आपको तलाश थी? इसे एक बंद कहा जाता है ।


14
यह बहुत बेहतर स्पष्टीकरण है। मैंने अपना जवाब
pyfunc

बस योग (x, y) को क्यों न करें: वापसी x + y?
आम

4
@ एमंगो: यह अवधारणा को व्यक्त करने के लिए सिर्फ एक खिलौना उदाहरण है - वास्तविक उपयोग में क्या do_it()होता है जो संभवतः एक returnबयान में कुछ अंकगणित द्वारा नियंत्रित किया जा सकता है की तुलना में थोड़ा अधिक जटिल होगा ।
13

2
@ मिंगो ने आपके प्रश्न का उत्तर थोड़े अधिक उपयोगी उदाहरण के साथ दिया। stackoverflow.com/a/24090940/2125392
CivFan

10
यह प्रश्न का उत्तर नहीं देता है।
हांसू

49

ऐसा करने से आपको वास्तव में बहुत फायदा नहीं होता है, वास्तव में यह धीमा हो method_aजाता है क्योंकि यह हर बार जब यह कहा जाता है, तो दूसरे फ़ंक्शन को परिभाषित और फिर से जोड़ देगा। यह देखते हुए, यह संभवतः एक निजी विधि - यानी यह इंगित करने के लिए अंडरस्कोर के साथ फ़ंक्शन नाम को उपसर्ग करना बेहतर होगा _method_b

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

अपडेट करें:

यहां सबूत है कि उन्हें घोंसला बनाना धीमा है (पायथन 3.6.1 का उपयोग करके), हालांकि इस तुच्छ मामले में बहुत अधिक नहीं है:

setup = """
class Test(object):
    def separate(self, arg):
        some_data = self._method_b(arg)

    def _method_b(self, arg):
        return arg+1

    def nested(self, arg):

        def method_b2(self, arg):
            return arg+1

        some_data = method_b2(self, arg)

obj = Test()
"""
from timeit import Timer
print(min(Timer(stmt='obj.separate(42)', setup=setup).repeat()))  # -> 0.24479823284461724
print(min(Timer(stmt='obj.nested(42)', setup=setup).repeat()))    # -> 0.26553459700452575

नोट मैंने selfउन्हें वास्तविक तरीकों की तरह बनाने के लिए आपके नमूना फ़ंक्शंस में कुछ तर्क जोड़े (हालाँकि method_b2अभी भी तकनीकी रूप से Testकक्षा की एक विधि नहीं है )। इसके अलावा नेस्टेड फ़ंक्शन वास्तव में आपके विपरीत, उस संस्करण में कहा जाता है।


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

7
हाँ, आपको आंतरिक फ़ंक्शन के लिए कई कॉल की आवश्यकता होगी। यदि आप इसे लूप में कह रहे हैं, या केवल एक मुट्ठी भर से अधिक है, तो फ़ंक्शन के लिए एक स्थानीय नाम होने का लाभ फ़ंक्शन बनाने की लागत को पछाड़ना शुरू कर देगा। मेरे परीक्षणों में, ऐसा तब होता है जब आप आंतरिक कार्य को लगभग 3-4 बार कहते हैं। बेशक, आप फ़ंक्शन के लिए एक स्थानीय नाम को परिभाषित करके (जैसे लगभग लागत के बिना) एक ही लाभ प्राप्त कर सकते हैं, उदाहरण के लिए method_b = self._method_bऔर फिर method_bदोहराया विशेषता लुकअप से बचने के लिए कॉल करें । (ऐसा होता है कि मैं हाल ही में सामान की एक बहुत कुछ कर रहा है। :)
1

3
@ मानवता: हाँ, यह सच है। मैंने अपने समय परीक्षण को संशोधित किया, इसलिए इसने माध्यमिक फ़ंक्शन को 30 कॉल किए और परिणाम बदल गए। इस उत्तर को देखने का मौका मिलने के बाद मैं अपना उत्तर हटा दूंगा। ज्ञानोदय के लिए धन्यवाद।
मार्टिउ

2
बस मेरे -1 को समझाना चाहता था क्योंकि यह एक सूचनात्मक उत्तर है, फिर भी: मैंने इसे -1 दिया क्योंकि यह एक तुच्छ प्रदर्शन अंतर पर ध्यान केंद्रित करता है (अधिकांश स्थितियों में कोड ऑब्जेक्ट निर्माण केवल फ़ंक्शन के निष्पादन समय का एक अंश लेगा )। इन मामलों में विचार करना महत्वपूर्ण है कि क्या इनलाइन फ़ंक्शन होने से कोड पठनीयता और स्थिरता में सुधार हो सकता है, जो मुझे लगता है कि यह अक्सर होता है क्योंकि आपको प्रासंगिक कोड खोजने के लिए फ़ाइलों के माध्यम से खोज / स्क्रॉल नहीं करना पड़ता है।
ब्लिक्स

2
@ ब्लिक्स: मुझे लगता है कि आपका तर्क त्रुटिपूर्ण (और डाउन-वोट अनुचित) है क्योंकि यह अत्यंत संभावना नहीं है कि एक ही वर्ग का एक और तरीका एक ही कक्षा में दूसरे से बहुत "दूर" होगा जब भी वह नेस्टेड नहीं है (और बहुत संभावना नहीं है) एक अलग फ़ाइल में हो)। इसके अलावा मेरे जवाब में पहला वाक्य यह है कि "आप वास्तव में ऐसा करने से बहुत लाभ नहीं उठाते हैं" जो इंगित करता है कि यह एक तुच्छ अंतर है।
6

27

किसी फ़ंक्शन के अंदर एक फ़ंक्शन आमतौर पर क्लोजर के लिए उपयोग किया जाता है ।

(एक भी नहीं है विवाद का बहुत अधिक वास्तव में क्या करता है को बंद करने के लिए एक बंद ।)

यहां बिल्ट-इन का उपयोग करके एक उदाहरण दिया गया है sum()। यह startएक बार परिभाषित करता है और तब से इसका उपयोग करता है:

def sum_partial(start):
    def sum_start(iterable):
        return sum(iterable, start)
    return sum_start

उपयोग में:

>>> sum_with_1 = sum_partial(1)
>>> sum_with_3 = sum_partial(3)
>>> 
>>> sum_with_1
<function sum_start at 0x7f3726e70b90>
>>> sum_with_3
<function sum_start at 0x7f3726e70c08>
>>> sum_with_1((1,2,3))
7
>>> sum_with_3((1,2,3))
9

अंतर्निहित अजगर बंद

functools.partial एक बंद का एक उदाहरण है।

अजगर डॉक्स से , यह लगभग बराबर है:

def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

(उत्तर के लिए नीचे @ user225312 कुडोस। मुझे यह उदाहरण पता लगाना आसान है, और उम्मीद है कि @ आम की टिप्पणी का जवाब देने में मदद मिलेगी।)


-1 हाँ, वे आमतौर पर बंद के रूप में उपयोग किया जाता है। अब सवाल फिर से। उन्होंने मूल रूप से पूछा कि क्या वह जिस अवधारणा को दिखाता है उसका उपयोग केस बी के लिए किया जा सकता है। उसे यह बताना कि यह अक्सर मामले के लिए उपयोग किया जाता है एक बुरा जवाब नहीं है, लेकिन इस प्रश्न के लिए गलत है। वह रुचि रखता है कि क्या उदाहरण के लिए एनकैप्सुलेशन के लिए उपरोक्त कार्य करना अच्छी बात है।
Mayou36

@ Mayou36 निष्पक्ष होने के लिए, सवाल बल्कि खुले अंत में है - हर संभव मामले का जवाब देने की कोशिश करने के बजाय, मैंने एक पर ध्यान केंद्रित करना सबसे अच्छा समझा। इसके अलावा सवाल बहुत स्पष्ट नहीं है। उदाहरण के लिए, यह दूसरे उदाहरण में स्पष्ट रूप से बंद हो जाता है, भले ही इसका मतलब यह नहीं था कि इसका क्या मतलब था।
CivFan

@ Mayou36 "उन्होंने मूल रूप से पूछा कि क्या वह दिखाता है कि केस बी के लिए इस्तेमाल किया जा सकता है।" नहीं, सवाल पूछता है कि क्या इसका इस्तेमाल किया जाना चाहिए। ओपी पहले से ही जानता है कि इसका इस्तेमाल किया जा सकता है।
CivFan

1
ठीक है, "अगर method_b के लिए आवश्यक है और केवल method_a से कॉल किया जाता है, तो क्या मुझे method_a के अंदर method_b घोषित करना चाहिए?" काफी स्पष्ट है और क्लोजर से कोई लेना-देना नहीं है, है ना? हाँ, मैं मानता हूँ, मैं का इस्तेमाल किया जा सकता है के रास्ते में होना चाहिए । लेकिन इसका क्लोजर से कोई लेना-देना नहीं है ... मुझे आश्चर्य है कि क्लोजर के बारे में इतने सारे उत्तर और ओपी द्वारा पूरी तरह से अलग प्रश्न पूछे जाने पर उनका उपयोग कैसे किया जाए।
मयू ३६

@ Mayou36 यह प्रश्न देखने में मदद कर सकता है कि आप इसे कैसे देखते हैं, और इसे संबोधित करने के लिए एक और प्रश्न खोलें।
CivFan

17

आम तौर पर, नहीं, कार्यों के अंदर कार्यों को परिभाषित नहीं करते हैं।

जब तक आपके पास वास्तव में अच्छा कारण नहीं है। जो आप नहीं करते हैं।

क्यों नहीं?

कार्यों के अंदर कार्यों को परिभाषित करने का एक बहुत अच्छा कारण क्या है ?

जब आप वास्तव में चाहते हैं तो एक राज्य बंद हो जाता है


1
यह उत्तर आपके लिए @ Mayou36 है।
CivFan

2
हाँ, धन्यवाद, यह वह उत्तर है जिसकी मुझे तलाश थी। यह संभव तरीके से सवाल का जवाब देता है। हालांकि यह कड़ाई से एक या दूसरे को नहीं कहता है, लेकिन यह इनलाइन परिभाषाओं को कारण बताते हुए बहुत हतोत्साहित करता है। कि कैसे (pythonic :)) उत्तर होना चाहिए!
मयउ ३६

10

यह वास्तव में एक दूसरे के अंदर एक समारोह घोषित करने के लिए ठीक है। यह विशेष रूप से उपयोगी सज्जाकार बना रहा है।

हालांकि, अंगूठे के एक नियम के रूप में, यदि फ़ंक्शन जटिल है (10 से अधिक लाइनें) यह मॉड्यूल स्तर पर घोषित करने के लिए एक बेहतर विचार हो सकता है।


2
यह संभव है, लेकिन मैं सहमत हूं, आपको इसे करने के लिए एक अच्छे कारण की आवश्यकता है। यह एक ऐसे कार्य के लिए एक पूर्ववर्ती अंडरस्कोर का उपयोग करने के लिए अधिक अजगर होगा जिसे केवल आपकी कक्षा के भीतर उपयोग करने का इरादा था।
चामुलीग

3
एक वर्ग के भीतर, हाँ, लेकिन केवल एक फ़ंक्शन के बारे में क्या ? एनकैप्सुलेशन पदानुक्रमित है।
पॉल ड्रेपर

@PaDDraper "इनकैप्सुलेशन पदानुक्रमित है" - नहीं! कौन कहता है? एनकैप्सुलेशन केवल कुछ विरासत की तुलना में बहुत व्यापक है।
Mayou36

7

मुझे यह सवाल इसलिए मिला क्योंकि मैं एक सवाल करना चाहता था कि अगर कोई नेस्टेड फ़ंक्शन का उपयोग करता है तो प्रदर्शन प्रभाव क्यों होता है। मैंने क्वाड कोर 2.5 गीगाहर्ट्ज इंटेल i5-2530M प्रोसेसर के साथ विंडोज नोटबुक पर पायथन 3.2.5 का उपयोग करके निम्नलिखित कार्यों के लिए परीक्षण चलाए।

def square0(x):
    return x*x

def square1(x):
    def dummy(y):
        return y*y
    return x*x

def square2(x):
    def dummy1(y):
        return y*y
    def dummy2(y):
        return y*y
    return x*x

def square5(x):
    def dummy1(y):
        return y*y
    def dummy2(y):
        return y*y
    def dummy3(y):
        return y*y
    def dummy4(y):
        return y*y
    def dummy5(y):
        return y*y
    return x*x

मैंने निम्न 20 बार, वर्ग 1, वर्ग 2 और वर्ग 5 के लिए भी मापा:

s=0
for i in range(10**6):
    s+=square0(i)

और निम्नलिखित परिणाम मिले

>>> 
m = mean, s = standard deviation, m0 = mean of first testcase
[m-3s,m+3s] is a 0.997 confidence interval if normal distributed

square? m     s       m/m0  [m-3s ,m+3s ]
square0 0.387 0.01515 1.000 [0.342,0.433]
square1 0.460 0.01422 1.188 [0.417,0.503]
square2 0.552 0.01803 1.425 [0.498,0.606]
square5 0.766 0.01654 1.979 [0.717,0.816]
>>> 

square0कोई नेस्टेड फ़ंक्शन नहीं है, square1एक नेस्टेड फ़ंक्शन है, square2दो नेस्टेड फ़ंक्शन हैं और square5पांच नेस्टेड फ़ंक्शन हैं। नेस्टेड फ़ंक्शन केवल घोषित किए जाते हैं, लेकिन कॉल नहीं किए जाते हैं।

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

इस उत्पादन को उत्पन्न करने वाले पूरे परीक्षण के लिए पायथन फ़ाइल को आइडोन पर पाया जा सकता है ।


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

-1 कृपया प्रश्न पर फिर से विचार करें। यद्यपि आप बता सकते हैं कि यह शायद थोड़ा धीमा है, उन्होंने पूछा कि क्या ऐसा करना एक अच्छा विचार है, मुख्य रूप से प्रदर्शन के कारण नहीं बल्कि सामान्य अभ्यास के कारण।
Mayou36

@ Mayou36 क्षमा करें, प्रश्न और उत्तर पोस्ट किए जाने के तीन साल बाद मैं नहीं करूंगा।
चमत्कार 173

ठीक है, दुर्भाग्य से, अभी भी कोई भी स्वीकृत (या अच्छा) उत्तर उपलब्ध नहीं है।
मेयू ३६

4

यह एक्सपोजर एपीआई के बारे में सिर्फ एक सिद्धांत है।

अजगर का उपयोग करना, बाहरी अंतरिक्ष (मॉड्यूल या वर्ग) में एक्सपोज़र एपीआई से बचने के लिए एक अच्छा विचार है, फ़ंक्शन एक अच्छा एनकैप्सुलेशन स्थान है।

यह एक अच्छा विचार हो सकता है। जब आप सुनिश्चित करें

  1. आंतरिक फ़ंक्शन केवल बाहरी फ़ंक्शन द्वारा उपयोग किया जाता है।
  2. इनसाइडर फ़ंक्शन का अपना उद्देश्य समझाने के लिए एक अच्छा नाम है क्योंकि कोड बात करता है।
  3. कोड सीधे आपके सहकर्मियों (या अन्य कोड-रीडर) द्वारा नहीं समझा जा सकता है।

भले ही, इस तकनीक के दुरुपयोग के कारण समस्याएं हो सकती हैं और इसका मतलब है कि डिजाइन दोष हो सकता है।

बस मेरे एक्सप से, शायद आपके सवाल को गलत समझे।


4

तो अंत में यह काफी हद तक एक सवाल है कि पायथन कार्यान्वयन कितना स्मार्ट है या नहीं, विशेष रूप से आंतरिक कार्य के मामले में एक बंद होने का नहीं है, लेकिन बस एक फ़ंक्शन में केवल सहायक की आवश्यकता है।

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

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

तो मैं कहूंगा कि आम तौर पर उनका उपयोग करते हैं, लेकिन जब आप वास्तव में प्रदर्शन के बारे में चिंतित होते हैं, तो संभावित प्रदर्शन हिट के बारे में जानते हैं और केवल उन्हें हटा देते हैं यदि आप वास्तविक रूपरेखा करते हैं जो यह दर्शाता है कि वे सबसे अच्छा हटाए जाते हैं।

आपके द्वारा लिखे गए सभी अजगर कोड में "इनर फंक्शंस बीएडी" का उपयोग करके समय से पहले अनुकूलन न करें। कृप्या।


जैसा कि अन्य उत्तरों से पता चलता है, आपके पास वास्तव में प्रदर्शन हिट नहीं हैं।
Mayou36

1

यह उस तरह से पूरी तरह से ठीक है, लेकिन जब तक आपको किसी क्लोजर का उपयोग करने या फ़ंक्शन को वापस करने की आवश्यकता नहीं होती है जो मैं संभवतः मॉड्यूल स्तर पर रखूंगा। मुझे लगता है कि दूसरे कोड उदाहरण में आप का मतलब है:

...
some_data = method_b() # not some_data = method_b

अन्यथा, some_data फ़ंक्शन होगा।

इसे मॉड्यूल स्तर पर रखने से अन्य कार्य मेथड__ () का उपयोग करने की अनुमति देंगे और यदि आप प्रलेखन के लिए स्फिंक्स (और ऑटोडोक) जैसी किसी चीज का उपयोग कर रहे हैं , तो यह आपको मेथड_ बी के दस्तावेज की अनुमति देगा।

आप एक कक्षा में कार्यक्षमता को दो तरीकों से रखने पर विचार कर सकते हैं यदि आप ऐसा कुछ कर रहे हैं जो किसी वस्तु द्वारा प्रतिनिधित्व योग्य हो सकता है। इसमें तर्क अच्छी तरह से शामिल हैं, भले ही आप सभी की तलाश कर रहे हों।


1

कुछ ऐसा करें:

def some_function():
    return some_other_function()
def some_other_function():
    return 42 

यदि आप some_function()इसे चलाने के लिए थे तो फिर चलाएंगे some_other_function()और 42 को लौटाएंगे।

संपादित करें: मैंने मूल रूप से कहा था कि आपको किसी फ़ंक्शन को दूसरे के अंदर परिभाषित नहीं करना चाहिए, लेकिन यह इंगित किया गया था कि यह कभी-कभी ऐसा करने के लिए व्यावहारिक है।


मैं उन प्रयासों की सराहना करता हूं, जिन्हें आपने अपने उत्तरों में डाला है, लेकिन आपका निर्देशन प्रत्यक्ष और बिंदु तक था। अच्छा लगा।
C0NFUS3D

1
क्यों? आपको ऐसा क्यों नहीं करना चाहिए? क्या यह बहुत अच्छा नहीं है? मुझे कोई तर्क याद आ रहा है। -1
मयउ 36

@ Mayou36 मुझे नहीं पता था कि मेरी टिप्पणी लिखने के समय क्या इनकैप्सुलेशन था, और न ही मुझे वास्तव में पता है कि यह अब क्या है। मुझे लगा कि यह करना अच्छा नहीं है। क्या आप समझा सकते हैं कि किसी फ़ंक्शन को किसी दूसरे के अंदर परिभाषित करने के बजाय, इसे उसके बाहर परिभाषित करने के बजाय क्यों फायदेमंद होगा?
mdlp0716

2
हाँ मैं कर सकता हूँ। आप इनकैप्सुलेशन की अवधारणा को देख सकते हैं, लेकिन संक्षेप में: उस जानकारी को छिपाएं जिसकी आवश्यकता नहीं है और केवल उस उपयोगकर्ता को उजागर करें जिसे जानना आवश्यक है। जिसका अर्थ है, बस बाहर कुछ some_other_function को परिभाषित करना नामस्थान में कुछ और जोड़ता है जो वास्तव में पहले फ़ंक्शन के लिए कसकर बाध्य है। या चर के संदर्भ में सोचें: आपको वैश्विक चर बनाम स्थानीय चर की आवश्यकता क्यों है? किसी फ़ंक्शन के अंदर सभी वेरिएबल्स को परिभाषित करना, यदि संभव हो तो बेहतर है तो केवल एक ही फ़ंक्शन के अंदर उपयोग किए जाने वाले वैरिएबल के लिए वैश्विक चर का उपयोग करना । यह अंत में जटिलता को कम करने के बारे में है।
मयउ ३६

0

वैश्विक चर को परिभाषित करने से बचने के लिए आप इसका उपयोग कर सकते हैं। यह आपको अन्य डिजाइनों के लिए एक विकल्प देता है। 3 डिजाइन एक समस्या का समाधान प्रस्तुत करते हैं।

ए) ग्लोबल्स के बिना कार्यों का उपयोग करना

def calculate_salary(employee, list_with_all_employees):
    x = _calculate_tax(list_with_all_employees)

    # some other calculations done to x
    pass

    y = # something 

    return y

def _calculate_tax(list_with_all_employees):
    return 1.23456 # return something

बी) ग्लोबल्स के साथ कार्यों का उपयोग करना

_list_with_all_employees = None

def calculate_salary(employee, list_with_all_employees):

    global _list_with_all_employees
    _list_with_all_employees = list_with_all_employees

    x = _calculate_tax()

    # some other calculations done to x
    pass

    y = # something

    return y

def _calculate_tax():
    return 1.23456 # return something based on the _list_with_all_employees var

C) किसी अन्य फ़ंक्शन के अंदर फ़ंक्शन का उपयोग करना

def calculate_salary(employee, list_with_all_employees):

    def _calculate_tax():
        return 1.23456 # return something based on the list_with_a--Lemployees var

    x = _calculate_tax()

    # some other calculations done to x
    pass
    y = # something 

    return y

समाधान C) बाहरी फ़ंक्शन के दायरे में चर का उपयोग करने की अनुमति देता है बिना उन्हें आंतरिक फ़ंक्शन में घोषित करने की आवश्यकता होती है। कुछ स्थितियों में उपयोगी हो सकता है।


0

समारोह में अजगर

def Greater(a,b):
    if a>b:
        return a
    return b

def Greater_new(a,b,c,d):
    return Greater(Greater(a,b),Greater(c,d))

print("Greater Number is :-",Greater_new(212,33,11,999))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.