पायथन फ़ंक्शन कॉल में अप्रयुक्त वापसी मापदंडों के लिए किस शैली का उपयोग करना है


30

क्या उन परिस्थितियों को संभालने के लिए कोई अनुशंसित / आम तौर पर स्वीकार की गई कोडिंग शैली है जहां कोई फ़ंक्शन मानों का टपल देता है, लेकिन उनमें से केवल एक मान का उपयोग किया जाता है (ध्यान दें कि यह ज्यादातर लाइब्रेरी फ़ंक्शंस के लिए होता है जिसे मैं बदल नहीं सकता - एक आवरण के आसपास लिखना कॉल शायद ओवरकिल का एक सा है ...)? करने के बजाय

a, b, c = foo()

और फिर बस का उपयोग नहीं कर रहा है bऔर c, निम्नलिखित में से कौन से वेरिएंट को प्राथमिकता दी जानी चाहिए (या क्या कोई दूसरा है?)

वेरिएंट 1 (अंडरस्कोर)

a, _, _ = foo()

(जो बहुत स्पष्ट और सरल है लेकिन _ = gettext.gettextअनुवाद का उपयोग करने वाले कई अनुप्रयोगों में उपयोग के साथ टकरा सकता है )

वेरिएंट 2 (डमी नाम)

a, unused, unused = foo()

(बहुत आकर्षक नहीं, मुझे लगता है, उसी तरह अन्य नामों के लिए भी जाता है dummy)

वेरिएंट 3 (इंडेक्स)

a = foo()[0]

(मुझे ()[0]अन-पाइथोनिक लगता है ...)


यह मेरे पूर्व उत्तर के विपरीत है, वैरिएंट 3 के साथ क्या होता है जब आप अब रिटर्न मानों का 2/3 संदर्भ लेना चाहते हैं? मैंने अपना उत्तर हटा दिया क्योंकि मुझे एहसास हुआ कि मैं इसे सही ठहराने के लिए पायथन के बारे में पर्याप्त नहीं जानता था।
क्रेजी

@ क्रेज: आपके द्वारा हटाए जाने से पहले मैंने आपका उत्तर नहीं देखा था ... क्या आप पूछ रहे हैं कि क्या a, b = foo()[0:2]काम करेगा? यदि हाँ: हाँ, यह करता है :)
user49643

ठीक यही मैं पूछ रहा था। अगर वह काम करता है (जैसा कि आपने कहा कि यह करता है) मैं संस्करण 3 का उपयोग करता हूं। मैं यह जानकारी देते हुए अपने जवाब को फिर से भेज रहा हूं।
क्रैज

3
संयोग से, इन दिनों आप 'विस्तारित' अनपैकिंग के लिए बल्कि सुंदर वाक्यविन्यास का उपयोग कर सकते हैं : a, *_ = foo()पहले वाले को छोड़कर सभी मूल्यों को दूर कर देगा।
बेंजामिन हॉजसन ने

जवाबों:


17

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

नाम व्यक्तिगत रूप से मुझे परेशान करते हैं dummyया unusedकरते हैं, और मैं उन्हें बहुत बार नहीं देखता (पायथन में, वह है - मैं एक डेल्फी कोडबेस को जानता हूं जो dummyउदारतापूर्वक उपयोग करता है, और यह प्रश्न में कार्यक्रम से जुड़ी लिपियों में भी लीक हो गया है)। मैं आपको इसके खिलाफ सलाह दूंगा।

लौटे हुए टपल में से केवल एक आइटम निकालना ठीक है। यह अप्रयुक्त मूल्यों की संख्या प्राप्त करने के साथ कुछ परेशानी भी बचाता है। ध्यान दें कि इसके दो संभावित डाउनसाइड हैं:

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

मैंने वास्तव में अपने प्रश्न में गेटटेक्स्ट का उल्लेख किया है :) वैसे भी, मैंने आपके उत्तर को स्वीकार कर लिया है - ऐसा लगता है कि कोई स्पष्ट एकल स्वीकृत शैली नहीं है, लेकिन आपके उत्तर ने कुछ दिलचस्प बिंदु उठाए हैं।
user49643

गेटटेक्स्ट (या दुभाषिया में इसी तरह की समस्याओं से बचने के लिए) के साथ समस्याओं से बचने के लिए आप सिंगल के बजाय डबल अंडरस्कोर (उर्फ डंडर्स) का उपयोग कर सकते हैं।
ज़ीम

21

Pylint ने मुझे इस तरह से करने की आदत में डाल दिया है:

widget, _parent, _children = f()

यही है, अप्रयुक्त परिणामों का एक वर्णनात्मक नाम है जो _ द्वारा उपसर्ग करता है। Pylint स्थानीय लोगों को _ के साथ उपसर्ग के रूप में मानता है, अप्रयुक्त और ग्लोबल्स या विशेषताओं को _ के साथ उपसर्ग के रूप में निजी।


3

यदि आपके पूरे प्रोजेक्ट में, आप केवल एक बार ऐसा कर रहे हैं या बहुत कम ही विशेष रूप से कार्य कर रहे हैं, तो मैं वेरिएंट 1 का उपयोग करूंगा यदि आप जानते हैं gettextकि उस मॉड्यूल में कोई समस्या नहीं है, और अन्यथा वेरिएंट 3।

दूसरी ओर, यदि आप यह बहुत कुछ कर रहे थे - और विशेष रूप से यदि हर बार आप रिटर्न मानों का एक अलग सबसेट चाहते हैं (केवल एक आवरण बनाने के लिए जिसे आप असभ्य के बारे में परवाह करते हैं), तो एक रैपर लिखना फायदेमंद हो सकता है यह परिणामों को एक नामित टपल , या किसी अन्य वर्णनात्मक वर्ग के उदाहरण में डालता है , जो आपको ऐसा करने देगा:

bar = foo()

और फिर साथ काम करते हैं bar.a, bar.bऔर bar.c


2

जैसा कि दूसरों ने कहा है, अंडरस्कोर ( _) मानक है। लेकिन अगर अनुवाद के लिए अंडरस्कोर का उपयोग किया जा रहा है, तो मुझे लगता है कि डबल अंडरस्कोर सबसे अच्छा विकल्प है।

var, __, value = "VAR=value".partition('=')

इनसे बेहतर:

var, unused, value = "VAR=value".partition('=')

var, unused_del, value = "VAR=value".partition('=')

var, _del, value = "VAR=value".partition('=')


1

मैं एक गैर-पायथन प्रोग्रामर हूं, लेकिन मेरे लिए तीसरा संस्करण सबसे अधिक समझ में आता है।

वैरिएंट 3 में आप बिल्कुल स्पष्ट हैं कि आपके मूल्यों के साथ क्या व्यवहार है। संस्करण 1 और 2 में, आप मानों को चर में वापस भेज रहे हैं, और इस प्रकार, उनका उपयोग किया जा सकता है। आपने उन्हें अस्पष्ट रूप से नामित किया होगा, लेकिन खराब नामकरण वास्तव में किसी भी समस्या का समाधान नहीं है।

स्पष्टता के अलावा, आप स्मृति में स्लॉट के लिए अप्रयुक्त मान क्यों निर्दिष्ट करना चाहते हैं (जैसा कि संस्करण 1 और 2 में)? यह स्मृति प्रबंधन के मामले में एक खराब समाधान होगा।


यदि आप इसे हमेशा एक ही चर पर रखते हैं तो क्या मेमोरी की समस्या किसी भी समय केवल एक ही चर का आकार नहीं होगी? मुझे नहीं लगता कि यह एक मुद्दा होना चाहिए।
माइकल मैकक्वाड

-2

यहां एक सामान्य नियम है: यदि दिए गए मानों में से केवल 1 का उपयोग किया जाता है, तो बस उस 1 मान को वापस क्यों नहीं किया जाता है? यदि झंडा कई स्थानों से बुलाया जा रहा है, तो ध्वज को उसी के अनुसार रखें और ध्वज के अनुसार मान लौटाएं।

संपादित करें:

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


-1 मुझे लग रहा है कि वह समारोह को परिभाषित नहीं कर रहा है, और इस प्रकार वह जो भी लौटता है उसे बदल नहीं सकता है। मुझे लगता है कि जब वह समारोह में 3 मान लौटाता है, तो उसका जिक्र होता है, लेकिन वह केवल अपने वर्तमान उपयोग के मामले में 1 की परवाह करता है।
क्रेजी

@ क्रेज: हां, मेरा मतलब था कि मैं ऐसे कार्य कर सकता हूं जिन्हें मैं बदल नहीं सकता - मैंने अपने प्रश्न में एक नोट जोड़ा जिसमें स्पष्ट किया गया था।
user49643

क्या आप ओवरहेड के बारे में निश्चित हैं? मैंने एक बहुत ही सरल ipython टेस्ट की कोशिश की: %timeit a, _, _ = foo()बनाम %timeit a = foo()[0]जिसके परिणामस्वरूप 123ns बनाम 109ns आया, यानी कि टुकड़ा करने की क्रिया वास्तव में मूल्य अनपैकिंग की तुलना में तेज है। या आपके मन में कोई विशेष स्थिति थी?
user49643

2
एक और प्रशंसनीय परिदृश्य यह है कि आपको कुछ कॉल के लिए सभी मूल्यों की आवश्यकता नहीं है ।
कीथ थॉम्पसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.