पाइथन के ठोस उदाहरण "इसे करने का केवल एक ही तरीका है" अधिकतम [बंद]


34

मैं पायथन सीख रहा हूं और PEP 20 के ज़ेन ऑफ़ पायथन में निम्नलिखित बिंदुओं से अंतर्ग्रथित हूँ :

वहाँ एक होना चाहिए - और अधिमानतः इसे करने के लिए केवल एक ही - स्पष्ट तरीका। हालांकि यह तरीका पहली बार में स्पष्ट नहीं हो सकता जब तक कि आप डच न हों।

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

जवाबों:


47

पर्ल जैसी भाषाओं की तुलना में, पायथन में सीमित संख्या में नियंत्रण निर्माण हैं:

  • केवल ifऔर नहीं unless,
  • केवल forवह जो दृश्यों पर आधारित है और foreachसी या शैली नहीं है for,
  • केवल वही whileजो हर लूप की स्थिति की जांच करता है और नहीं do-while,
  • केवल if-elifऔर नहीं switch,
  • केवल एक टिप्पणी का निर्माण है #, और हर पंक्ति के लिए आप बता सकते हैं कि क्या यह पिछली लाइनों को देखे बिना टिप्पणी की गई है या नहीं।

इसके अलावा, अपने स्रोत को इंडेंट करने का लगभग एक तरीका है; रचनात्मक इंडेंटेशन के अधिकांश मामलों को कृत्रिम रूप से बाहर रखा गया है।

यह मनुष्यों के लिए पायथन स्रोत को आसान बनाता है।

अंतर्निहित प्रकार और मानक पुस्तकालय में न्यूनतम-लेकिन-पूर्ण होने के प्रयास हैं।

  • परिवर्तनशील सूची के लिए आप केवल निर्मित listप्रकार का उपयोग करते हैं ; अधिकांश कार्यों के लिए यह O (1) है, और आपको कभी भी सही कार्यान्वयन का चयन नहीं करना होगा,
  • अपरिवर्तनीय सूचियों के लिए, समान रूप से, आप बस tupleप्रकार का उपयोग करते हैं ,
  • नक्शों के लिए, आप केवल ऐसे बिल्ट-इन का उपयोग करते हैं, dictजो कि ज्यादातर मामलों में कुशल हो, कोई विचार करने की आवश्यकता नहीं है जिसे उपयोग करने के लिए क्रियान्वयन करना है।

पायथन 3 इसे पूर्णांक तक विस्तारित करता है: कोई फर्क नहीं पड़ता कि आपका पूर्णांक कितना बड़ा है, आप एक ही प्रकार का उपयोग करते हैं और कभी भी ज़बरदस्ती की परवाह नहीं करते हैं।

पायथन सिंटैक्टिक शुगर से बचने की कोशिश करता है। लेकिन कभी-कभी यह स्पष्ट रूप से स्पष्ट करने के लिए सिंटैक्टिक चीनी को जोड़ता है। आप if foo is not Noneइसके बजाय लिख सकते हैं if not (foo is None)क्योंकि 'नहीं है' विशेष-आवरण है। अभी भी foo is not Noneआसानी से पढ़ता है, गलत व्याख्या नहीं की जा सकती है, और आपको सोचने की ज़रूरत नहीं है, आप सिर्फ स्पष्ट बात लिखते हैं।

बेशक, पायथन में अधिकांश जटिल चीजें कई तरीकों से की जा सकती हैं। आप घोषणा या सरल स्लॉट असाइनमेंट द्वारा कक्षाओं में विधियां जोड़ सकते हैं, आप कई रचनात्मक तरीकों से कार्यों के लिए तर्क पारित कर सकते हैं, आदि यह सिर्फ इसलिए है क्योंकि भाषा के आंतरिक अधिकतर उजागर होते हैं।

कुंजी यह है कि हमेशा एक तरीका होता है जो सबसे अच्छा, कवर-ऑल केस होता है। यदि अन्य तरीके मौजूद हैं, तो उन्हें समान विकल्पों (जैसे ifऔर unless) के रूप में नहीं जोड़ा गया था, लेकिन केवल आंतरिक कामकाज को उजागर करते हैं। धीरे-धीरे लेकिन लगातार ऐसे विकल्पों को ज्ञात सर्वोत्तम तंत्र को बढ़ाकर (समाप्त नहीं!) किया जाता है।

सज्जाकार AOP फ़ंक्शन कॉल को लपेटते हैं। 2.6 से पहले आपको __metaclass__क्लास के मेटाक्लास घोषित करने के लिए जादू के सदस्य का उपयोग करना था ; अब आप इसके लिए एक ही डेकोरेटर सिंटैक्स का उपयोग कर सकते हैं। 3.0 से पहले आपके पास दो तरह के स्ट्रिंग्स थे, बाइट-ओरिएंटेड और यूनिकोड, जिसे आप अनजाने में मिला सकते थे। अब आपके पास एकमात्र यूनिकोड strऔर एकमात्र बाइनरी-पारदर्शी है bytes, जिसे आप गलती से नहीं मिला सकते हैं।


3
एक नोट के रूप में, """टिप्पणियों (डोकस्ट्रिंग्स) को मत भूलना । ये कई लाइनों को फैलाते हैं।
अष्टस्रोत जूल २।

8
ट्रिपल-उद्धृत शाब्दिक केवल तार हैं, एकल-उद्धृत के समान हैं, लेकिन लाइन के अंत से बचने के बिना कई पंक्तियों को फैला सकते हैं। घोषणा के बाद एक स्ट्रिंग शाब्दिक अधिकार एक डॉक्टर स्ट्रिंग माना जाता है, और यह एक टिप्पणी नहीं है, यह आमतौर पर __doc__विशेषता के रूप में सुलभ है। लेकिन तार एक ऐसा क्षेत्र है जहाँ पायथन निश्चित रूप से कई 'सही तरीके' प्रदान करता है: एकल, दोहरे या तिहरे उद्धरण का उपयोग करें, जो निकटवर्ती शाब्दिक अर्थों में शामिल हों, rकच्चे शाब्दिक का उपयोग करें , आदि
9000

1
मुझे लगता है कि @ syrion की टिप्पणी "आप हमेशा यह तय कर सकते हैं कि क्या कोई रेखा टिप्पणी की गई है या नहीं बस इसे देख कर", जो "" तार के कारण सत्य नहीं है।
blubb

2
"यह मनुष्यों के लिए पायथन स्रोत को आसान बनाता है।" <- यह व्यक्तिपरक है
जिग्गी

2.7 में मेटाक्लास घोषणा कैसे बदल गई? मेटाक्लेसेस के लिए 2.7 डॉक्स में डेकोरेटर पैटर्न नहीं मिल सकता है।
Nick T

10

उदाहरण के एक और जोड़े हैं:
len()प्रत्येक अनुक्रम में मौजूद एक विधि के बजाय एक फ़ंक्शन है; यदि आप जावा के साथ तुलना करें आप .length, .size(), .getSize(), और अन्य तरीकों एक दृश्य में तत्वों की संख्या को खोजने के लिए।

एक और उदाहरण तथ्य यह .join()है कि एक stringविधि है, प्रत्येक क्रम में मौजूद एक विधि नहीं है। आपको यह जानने की आवश्यकता नहीं है कि क्या ज्वाइन पैरामीटर एक सूची, एक सेट, एक समझ, या जो भी है, यह काम करेगा।


8

C में एक चर के मान को बढ़ाने के कई संभावित तरीके हैं:

i++     // Post-increment, returns the number before the increment
++i     // Pre-increment, returns the number after the increment
i += 1 

प्रत्येक का मान बढ़ता जा रहा iहै 1, लेकिन प्रत्येक थोड़ा अलग है।

पायथन में, वास्तव में केवल एक ही रास्ता है; बस एक जोड़ें।

i += 1

और ऐसा करने के लिए एक से अधिक वाक्यात्मक रूप से मान्य तरीका है (उदाहरण के लिए i = i + 1), आप एक ही साइड इफेक्ट के साथ एक ही काम कर रहे हैं।


1
मैं कोई विशेषज्ञ नहीं हूं, लेकिन यह उदाहरण "विचार करने का केवल एक ही तरीका" का ठीक-ठीक उल्लंघन करता प्रतीत होता है। हमारे पास इसे करने के दो तरीके हैं, लेकिन जो अधिक स्पष्ट है? मेरी दृष्टि में पहला उदाहरण अधिक स्पष्ट है, जबकि दूसरा थोड़ा अधिक है, लेकिन किसी भी प्रोग्रामर के लिए कोई कम पठनीय या स्पष्ट नहीं है, जो बहुत मूल बातों से आगे बढ़ चुका है। आपके उत्तर के लिए धन्यवाद - यह विचार के लिए अच्छा भोजन है।
चार्ल्स रोपर

@Peter ((@Charles): वास्तव में, i = i + 1असाइनमेंट है, वेतन वृद्धि नहीं। अजगर में एक वृद्धि है i += 1। सी-शैली भाषाओं में आप लिख सकते हैं i++, ++iऔर i += 1
जोश के

2
आपकी "बहुत सी भ्रम" टिप्पणी के बारे में निश्चित नहीं है, आपके तीनों सी उदाहरण (आप चूक गए i += 1, बीटीडब्ल्यू) बिल्कुल उसी परिणाम का उत्पादन करते हैं। केवल समय मैं लोगों को भ्रमित होते हुए देखता हूं जब वे एक बड़ी अभिव्यक्ति के हिस्से के रूप में एक चर को पूर्व या बाद में बढ़ाते हैं, और यह आमतौर पर भाषा के संदर्भ के उपयुक्त अनुभाग को पढ़कर जल्दी से ठीक हो जाता है। व्यक्तिगत रूप से, मैं तथ्य यह है कि तुम दोनों से एक स्ट्रिंग के पांचवें चरित्र का उल्लेख कर सकते पर चुना है चाहते हैं str[4]या *(str+4), लेकिन शायद बहुत आसान था कि ...
TMN

2
@ टीएमएन: कुछ मामलों, जैसे max(i++, ++i)जल्दी ठीक नहीं हो सकते। सी में बहुत सारे "अपरिभाषित" और "कार्यान्वयन-निर्भर" व्यवहार के मामले हैं, सभी एक अच्छे कारण के लिए - लेकिन प्रत्येक एक नुकसान पैदा कर सकता है।
9000

@TMN: 4 [str] (C में मान्य, C ++ में मान्य नहीं हो सकता) का उल्लेख नहीं है।
वेटिन

6

एक अन्य संभावना सूची की समझ हो सकती है। पायथन में, आप यह कर सकते हैं:

new_list = []
    for item in list_of_items:
       if item < 10:
           new_list.append(item)

लेकिन "स्पष्ट" तरीका (यदि आप डच हैं या अजगर से अधिक परिचित हैं) तो ऐसा करने की एक सूची समझ के साथ होगी:

new_list = [item for item in list_of_items if item < 10]

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


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