वापसी, कोई नहीं लौटा, और कोई वापसी नहीं?


386

तीन कार्यों पर विचार करें:

def my_func1():
  print "Hello World"
  return None

def my_func2():
  print "Hello World"
  return

def my_func3():
  print "Hello World"

वे सभी वापस लौटते दिखाई देते हैं। क्या इन कार्यों के लौटे मूल्य के बीच कोई अंतर है? क्या एक बनाम दूसरे को पसंद करने के कोई कारण हैं?


40
ध्यान दें कि एक शैलीगत अंतर है। return Noneमेरा तात्पर्य यह है कि फ़ंक्शन का कभी-कभी एक गैर- Noneवापसी मान होता है, लेकिन इसके स्थान पर return None, ऐसा कोई वापसी मान नहीं होता है। returnमेरे लिए बिल्कुल भी नहीं लिखने का अर्थ है कि एक दिलचस्प रिटर्न वैल्यू, "फ़ंक्शन" के विपरीत "प्रक्रिया" की तरह थोड़े। returnतात्पर्य पिछले बिंदु के अनुसार एक "प्रक्रिया" से पहले से मौजूद है।

जवाबों:


500

वास्तविक व्यवहार पर, कोई अंतर नहीं है। वे सभी वापस आ गए Noneऔर यह बात है। हालांकि, इन सभी के लिए एक समय और स्थान है। निम्नलिखित निर्देश मूल रूप से हैं कि विभिन्न तरीकों का उपयोग कैसे किया जाना चाहिए (या कम से कम मुझे कैसे सिखाया जाता था कि उनका उपयोग किया जाना चाहिए), लेकिन वे पूर्ण नियम नहीं हैं, इसलिए यदि आप आवश्यक महसूस करते हैं तो आप उन्हें मिला सकते हैं।

का उपयोग करते हुए return None

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

निम्न उदाहरण में, हम वापसी person's motherअगर personदिए गए एक मानव है। यदि यह मानव नहीं है, तो हम वापस लौटते हैं Noneक्योंकि इसमें personकोई नहीं है mother(मान लीजिए कि यह जानवर या कुछ नहीं है)।

def get_mother(person):
    if is_human(person):
        return person.mother
    else:
        return None

का उपयोग करते हुए return

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

हमें 15 मिले हैं prisonersऔर हम जानते हैं कि उनमें से एक के पास चाकू है। हम prisonerएक - एक करके यह जांचते हैं कि उनके पास चाकू है या नहीं। यदि हम उस व्यक्ति को चाकू से मारते हैं, तो हम केवल फ़ंक्शन से बाहर निकल सकते हैं क्योंकि हम जानते हैं कि केवल एक चाकू है और बाकी का कोई कारण नहीं है prisoners। यदि हमें prisonerचाकू नहीं मिलता है , तो हम एक चेतावनी देते हैं। यह कई अलग-अलग तरीकों से किया जा सकता है और इसका उपयोग returnकरना शायद सबसे अच्छा तरीका भी नहीं है, लेकिन यह सिर्फ एक उदाहरण है कि returnकिसी समारोह से बाहर निकलने के लिए कैसे उपयोग किया जाए।

def find_prisoner_with_knife(prisoners):
    for prisoner in prisoners:
        if "knife" in prisoner.items:
            prisoner.move_to_inquisition()
            return # no need to check rest of the prisoners nor raise an alert
    raise_alert()

नोट: आपको कभी भी ऐसा नहीं करना चाहिए var = find_prisoner_with_knife(), क्योंकि रिटर्न वैल्यू पकड़े जाने का मतलब नहीं है।

returnबिल्कुल नहीं का उपयोग करना

यह भी वापस आ जाएगा None, लेकिन उस मूल्य का उपयोग या पकड़े जाने का मतलब नहीं है। इसका सीधा सा मतलब है कि फ़ंक्शन सफलतापूर्वक समाप्त हो गया। यह मूल रूप से की तरह ही है returnमें voidइस तरह के सी ++ या जावा जैसी भाषाओं में कार्य करता है।

निम्नलिखित उदाहरण में, हम व्यक्ति की माँ का नाम निर्धारित करते हैं और फिर कार्य सफलतापूर्वक पूरा करने के बाद बाहर निकलता है।

def set_mother(person, mother):
    if is_human(person):
        person.mother = mother

नोट: आपको कभी भी ऐसा नहीं करना चाहिए var = set_mother(my_person, my_mother), क्योंकि रिटर्न वैल्यू पकड़े जाने का मतलब नहीं है।


5
var = get_mother()ठीक है अगर आप varअन्य कार्यों के लिए गुजर रहे हैं जो स्वीकार करते हैं None- "कभी नहीं" थोड़ा चरम है
जॉलेब

अगर var = get_mother()कोई इस्तेमाल नहीं किया जा सकता है तो रिटर्न रिटर्न कैसे स्वीकार करना चाहिए ? IMHO ऐसा करना पूरी तरह से ठीक है। बस आपको इसे इस्तेमाल करने से पहले एक गैर Noneमूल्य के लिए जांचना सुनिश्चित करना if varहोगा।
winklerrr

मुझे लगा कि यह उल्लेख करना महत्वपूर्ण है कि यह केवल एक अच्छा सम्मेलन नहीं है, यह PEP8 द्वारा आवश्यक है। मैं आपकी प्रशंसा करने और इस पर PEP8 को उद्धृत करने का उत्तर देता हूं।
Fabiano

29

हां, वे सभी समान हैं।

हम व्याख्या किए गए मशीन कोड की समीक्षा करने के लिए पुष्टि कर सकते हैं कि वे सभी एक ही काम कर रहे हैं।

import dis

def f1():
  print "Hello World"
  return None

def f2():
  print "Hello World"
  return

def f3():
  print "Hello World"

dis.dis(f1)
    4   0 LOAD_CONST    1 ('Hello World')
        3 PRINT_ITEM
        4 PRINT_NEWLINE

    5   5 LOAD_CONST    0 (None)
        8 RETURN_VALUE

dis.dis(f2)
    9   0 LOAD_CONST    1 ('Hello World')
        3 PRINT_ITEM
        4 PRINT_NEWLINE

    10  5 LOAD_CONST    0 (None)
        8 RETURN_VALUE

dis.dis(f3)
    14  0 LOAD_CONST    1 ('Hello World')
        3 PRINT_ITEM
        4 PRINT_NEWLINE            
        5 LOAD_CONST    0 (None)
        8 RETURN_VALUE      

4
यहाँ सावधान ... dis.disरिटर्न None: -X
mgilson

एक स्ट्रिंग के रूप में डिस की आउटपुट प्राप्त करने का एकमात्र तरीका कुछ प्रकार के IO बफर (जैसे StringIO) पर रीडायरेक्ट करना है। फिर भी, सीधे-सीधे तुलना करना, ऐसा काम नहीं कर सकता क्योंकि मेरा मानना ​​है कि dis.disकुछ लाइन नंबरों की भी रिपोर्ट है ...
mgilson

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

19

वे प्रत्येक एक ही सिंगलटन लौटाते हैं None- कोई कार्यात्मक अंतर नहीं है।

मुझे लगता है कि returnजब तक आपको फ़ंक्शन को जल्दी से बाहर निकालने की आवश्यकता नहीं होती है (जिसमें कोई नंगे returnअधिक आम है), या इसके अलावा कुछ और वापस करने के लिए उचित रूप से बयान छोड़ना उचित है None। यह भी समझ में आता है और ऐसा लगता है कि return Noneजब यह एक समारोह में है कि एक और रास्ता है कि कुछ और के अलावा देता है लिखने के लिए मुहावरेदार लगता है Nonereturn Noneस्पष्ट रूप से लिखना पाठक के लिए एक दृश्य क्यू है कि एक और शाखा है जो कुछ और दिलचस्प लौटाता है (और उस कॉलिंग कोड को शायद दोनों प्रकार के रिटर्न मानों को संभालने की आवश्यकता होगी)।

अक्सर पायथन में, फ़ंक्शन जो सी में फ़ंक्शन की Noneतरह उपयोग किए जाते हैं void- उनका उद्देश्य आम तौर पर इनपुट तर्कों पर काम करना है (जब तक कि आप वैश्विक डेटा ( शूडर ) का उपयोग नहीं कर रहे हैं )। लौटना Noneआमतौर पर यह अधिक स्पष्ट करता है कि तर्कों को उत्परिवर्तित किया गया था। इससे यह थोड़ा और स्पष्ट हो जाता है कि return"भाषा सम्मेलनों" के दृष्टिकोण से कथन को छोड़ने का क्या अर्थ है ।

यदि आप एक कोड आधार में काम कर रहे हैं, तो कहा है कि पहले से ही इन चीजों के आसपास पूर्व निर्धारित सम्मेलनों है, मैं निश्चित रूप से कोड आधार एक समान रहने में मदद करने के लिए सूट का पालन करेंगे ...


1
या अधिक आम तौर पर, किसी भी समय एक returnबयान समाप्त किए बिना एक समारोह समाप्त होता है , यह वापस लौटता है None

यदि फ़ंक्शन मान वापस करने की उम्मीद है, तो रिटर्न स्टेटमेंट को छोड़ना मुहावरेदार नहीं है। केवल साइड इफेक्ट्स के माध्यम से काम करने वाले कार्यों को रिटर्न स्टेटमेंट को छोड़ देना चाहिए।
अणु

@ अणु - हाँ, मुझे लगता है कि शायद मैंने अपने स्पष्टीकरण में सबसे अच्छा काम नहीं किया। मैंने इसे ऊपर (बहुत बेहतर) उत्तर का पूर्ण क्लोन बनाकर अपडेट करने की कोशिश की है। मैं अभी भी इस पोस्ट से सुपर खुश नहीं हूँ ... मेरे हिस्से में से इसे हटाना चाहते हैं (क्योंकि ऊपर का उत्तर इतना बेहतर है) और मेरा कुछ हिस्सा इसे रखना चाहता है - 9 लोगों ने अब तक सोचा था कि यह अच्छा था एक कारण या दूसरा। हो सकता है कि मैंने किसी और चीज़ पर निशाना साधा हो?
mgilson

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

1
@ZAB - दोनों Rubyऔर Javascriptअजगर के समान दृष्टिकोण लेते हैं। मुझे यकीन है कि वहाँ कि कर रहा हूँ कर रहे हैं कि कहते हैं कि "शून्य" अभिव्यक्ति में उच्च स्तरीय भाषाओं का उदाहरण है, लेकिन मैं इस समय (शायद अगर आप समझते हैं पर किसी भी नहीं सोच सकते हैं Javaएक उच्च स्तरीय भाषा) ... कैसे होगा बंदर पैचिंग एक फ़ंक्शन (जो अन्य चीजों के बीच परीक्षणों में मॉकिंग के लिए उपयोगी है) एक काल्पनिक दुनिया में काम करता है जहां अजगर को एक voidकीवर्ड मिला जिसने इसे बनाया ताकि फ़ंक्शन कुछ भी वापस नहीं आए? (इसके अलावा, जैसा कि मैंने पहले कहा था, आपको मुझे यह समझाने की ज़रूरत नहीं है कि यह एक बुरा डिज़ाइन है। मैं कुछ भी नहीं कर सकता, भले ही आप सही हों)
mgilson

4

जैसा कि अन्य ने उत्तर दिया है, परिणाम बिल्कुल समान है, Noneसभी मामलों में वापस आ गया है।

अंतर शैलीगत है, लेकिन कृपया ध्यान दें कि PEP8 को संगत होने के लिए उपयोग की आवश्यकता है:

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

हाँ:

def foo(x):
    if x >= 0:
        return math.sqrt(x)
    else:
        return None

def bar(x):
    if x < 0:
        return None
    return math.sqrt(x)

नहीं:

def foo(x):
    if x >= 0:
        return math.sqrt(x)

def bar(x):
    if x < 0:
        return
    return math.sqrt(x)

https://www.python.org/dev/peps/pep-0008/#programming-recommendations


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

यदि आपको बिल्कुल भी वापसी की आवश्यकता नहीं है, तो आप मूल रूप से एक फ़ंक्शन के बजाय एक प्रक्रिया के रूप में कार्य करते हैं, इसलिए केवल returnकथन को शामिल न करें ।

यदि आप एक प्रक्रिया-प्रकार के फ़ंक्शन लिख रहे हैं और पहले लौटने का अवसर है (यानी आप पहले से ही उस बिंदु पर हैं और फ़ंक्शन के शेष को निष्पादित करने की आवश्यकता नहीं है) तो आप returnपाठक के लिए संकेत करने के लिए खाली s का उपयोग कर सकते हैं यह सिर्फ निष्पादन का एक प्रारंभिक समापन है और जो Noneमूल्य निहित है, उसका कोई मतलब नहीं है और इसे पकड़े जाने का मतलब नहीं है (प्रक्रिया-प्रकार फ़ंक्शन हमेशा Noneवैसे भी लौटता है)।


3

कार्यक्षमता के संदर्भ में ये सभी समान हैं, उनके बीच अंतर कोड पठनीयता और शैली में है (जो विचार करना महत्वपूर्ण है)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.