क्या ** कंवर एक एंटीपैटर्न है?


16

हमारे आंतरिक कोडबेस में हमारे पास बहुत सारे कोड होते हैं जो हमारे पुस्तकालयों को आंतरिक रूप से कहते हैं - इन पुस्तकालयों में अक्सर बहुत सारे तर्क होते हैं (सोचते हैं matplotlib) और हमारा कोड अक्सर केवल एक विशिष्ट कार्य कर रहा है और बस **kwargsअगले नाम से जाना जाता है।

उदाहरण के लिए:

def our_method(dataframe, **kwargs):
    result = do_something_with_data(dataframe)
    external_module.draw(result, **kwargs)

जबकि **kwargsहमें अपने पद्धति घोषणा में सभी मापदंडों को दोहराने से रोकता है, यह यह भी बेहद अपारदर्शी बनाता है कि कॉल करते समय कौन से तर्क मान्य हैं our_method- मुझे यह जानना होगा कि किस विधि को कहा जाता है, जिसे मैं अक्सर जानना नहीं चाहता।

इसमें आपको क्या फायदा होगा?

जवाबों:


16

डेवलपर्स द्वारा आपके कोड का उपयोग कैसे किया जाता है? दूसरे शब्दों में, वे यह निर्धारित करने के लिए वास्तव में क्या करते हैं कि किस तर्क का उपयोग किया जाना चाहिए और कैसे?

  • यदि वे आपके कोड से स्वचालित रूप से उत्पन्न प्रलेखन पर भरोसा करते हैं, और जनरेटर को कोई सुराग नहीं है कि इसके साथ क्या करना है **kwargs, तो यह वास्तव में समस्याग्रस्त है। दस्तावेज़ीकरण में तर्कों और उनके अर्थ की सूची खोजने के बजाय, उनके पास अस्पष्ट "यह कुछ तर्क लेता है" को छोड़कर पूरी तरह से कोई जानकारी नहीं है ।

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

  • यदि कोड उनका दस्तावेज है, तो डेवलपर्स जो **kwargsदो अतिरिक्त चरणों की आवश्यकता के साथ विधि का उपयोग करते हैं : उन्हें न केवल विधि के हस्ताक्षर को देखने की जरूरत है, बल्कि इसके वास्तविक कार्यान्वयन पर भी, अन्य विधि को खोजने के लिए, जिसे वह वास्तव में कहता है। फिर, उन्हें इस दूसरी विधि पर जाने की आवश्यकता है कि आखिरकार वे क्या ढूंढ रहे थे।

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

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

आखिरकार, आपके द्वारा लिखी गई विधि के भीतर आपके द्वारा कॉल की गई विधि के तर्कों को फिर से लिखने के लिए बहुत अधिक प्रयास नहीं करना चाहिए। उम्मीद है, अधिकांश विधियां छह से आठ से अधिक तर्क नहीं लेती हैं, और यदि वे करते हैं, तो अपने आप से पूछें कि क्या आपको कोड को फिर से भरना नहीं चाहिए। सभी मामलों में:

  • अपने तरीके के भीतर स्पष्ट तर्क बनाने के लिए बहुत अधिक प्रयास की आवश्यकता नहीं होती है,

  • आप चाहें, बाद में, वैसे भी तर्कों को मान्य कर सकते हैं (हालाँकि यदि आप इस बिंदु पर भरोसा करते हैं तो तर्क स्पष्ट करने के लिए, आप YAGNI का उल्लंघन करते हैं)।


मुझे वास्तव में यह उत्तर पसंद है और लगता है कि यह एक अच्छा है। दुर्भाग्य से, हमारे कई कोड में इस पद्धति का उपयोग करने के बहुत सारे सार्वजनिक तरीके हैं। लेकिन अब मेरे पास तर्क हैं कि हमें इसे बदलना चाहिए (और matplotlib को छोड़ना चाहिए, कभी एक क्रैपीयर "इंटरफ़ेस" नहीं देखा ..)
ईसाई Sauer

3

यदि अगले-स्तरीय फ़ंक्शन में __doc__ है, तो आप बस __doc__ को अपने नए फ़ंक्शन में कॉपी कर सकते हैं।

उदाहरण के लिए:

def a(x):
    """This function takes one parameter, x, and does nothing with it!"""
    pass

def b(**kwargs):
    a(**kwargs)

b.__doc__=a.__doc__

यह पुनरावर्ती रूप से लागू हो सकता है, और एक डेकोरेटर द्वारा लागू किया जा सकता है (जो कि उपयोगी हो सकता है यदि आप वैसे भी थोक में ऐसा कर रहे हैं)। __Doc__ स्ट्रिंग को जोड़ दिया जा सकता है, अंत में अधिक जोड़ने के लिए। इसका मतलब है कि दिखाए गए पैरामीटर अभी भी kwargs होंगे, लेकिन वास्तविक मापदंडों का वर्णन करने में मदद करने के लिए कम से कम प्रलेखन है।

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