दिलचस्प पोस्ट
दोनों बिन और जीएसी में डीएलएल, जो एक का उपयोग किया जाता है? ऐप के लिए पुश नोटिफिकेशन सेटिंग रीसेट करें jQuery जावास्क्रिप्ट regex बदलें with \ n विंडो का अनुरोध न करें। FATURE_ACTION_BAR समस्या रिवर्स इंजीनियरिंग से आपके एनएटीटी कोड को संरक्षित करने के लिए आप क्या उपयोग करते हैं? निष्पादन को अक्षम करें: डिफ़ॉल्ट-जार सी # में पैटर्न को अंतिम रूप दें / डिस्पोज़ करें वसंत MVC 3 नियंत्रक से केवल स्ट्रिंग संदेश लौटें सरणी डुप्लिकेट तत्वों को हटा दें HTML इकाई नाम (& nbsp;, & lt ;, & gt ;, आदि) को कैसे लिखूं इंटरनेट एक्सप्लोरर में सरल jQuery अजाक्स कॉल लीक्स मेमोरी प्ले फ्रेमवर्क और स्कला के साथ IntelliJ का उपयोग कैसे करें जावा का उपयोग करते हुए HTML फ़ाइल लिखें अजगर में सेलेनियम का उपयोग करके उपयोगकर्ता नाम और पासवर्ड भरें पांडा read_csv low_memory और dtype विकल्प

पायथन में, मुझे किसी विधि के बजाय फ़ंक्शन का उपयोग कब करना चाहिए?

अजगर का ज़ेन कहता है कि काम करने का एकमात्र तरीका होना चाहिए- फिर भी अक्सर यह तय करने की समस्या में पड़ता है कि किसी पद्धति का उपयोग करने के समय फ़ंक्शन बनाम कब उपयोग किया जाए।

चलो एक तुच्छ उदाहरण लेते हैं- एक शतरंज वस्तु मान लें कि बोर्ड पर सभी कानूनी राजा चालें उपलब्ध कराने के लिए हमें कुछ रास्ते की जरूरत है। क्या हम ChessBoard.get_king_moves () या get_king_moves (chess_board) लिखते हैं?

यहां कुछ संबंधित प्रश्न हैं जो मैंने देखा:

  • अजगर 'जादू विधियों' का उपयोग क्यों करता है?
  • क्या कोई कारण है कि पायथन स्ट्रिंग की स्ट्रिंग लम्बी विधि नहीं है?

मेरे पास उत्तर काफी हद तक अनिर्णीत थे:

अजगर कुछ कार्यक्षमता (जैसे list.index ()) के लिए तरीकों का उपयोग क्यों करता है, लेकिन अन्य के लिए फ़ंक्शन (जैसे लेन (सूची))?

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

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

रोचक होने पर, उपरोक्त वास्तव में यह नहीं बताया जाता है कि अपनाने की रणनीति क्या है।

यह एक कारण है – कस्टम विधियों के साथ, डेवलपर्स एक अलग पद्धति नाम चुनने के लिए स्वतंत्र होंगे, जैसे कि getLength (), लंबाई (), मिलीग्राम () या कुछ भी। पायथन सशक्त नामकरण को लागू करता है ताकि सामान्य फ़ंक्शन लेन () का उपयोग किया जा सके।

थोड़ा और दिलचस्प मेरा लेना यह है कि फ़ंक्शन एक अर्थ में हैं, इंटरफेस के पायथनिक संस्करण।

अन्त में, गुइडो से :

क्षमताओं / इंटरफेस के बारे में बात करते हुए मुझे हमारे "बदमाश" विशेष विधियों के कुछ नामों के बारे में सोचने लगा। भाषा संदर्भ में, यह कहते हैं, "एक क्लास कुछ विशेष आपरेशनों को लागू कर सकता है जिन्हें विशेष नामों के साथ विधियों को परिभाषित करके विशेष वाक्यविन्यास (जैसे कि अंकगणितीय संचालन या सबस्क्रिप्टिंग और टुकड़ों के टुकड़े) द्वारा लागू किया जाता है।" लेकिन इन सभी विधियां ऐसे विशेष नाम हैं __len__ नाम विशेष रूप से __len__ या __unicode__ जो वाक्य-रचना के समर्थन के बजाय निर्मित फ़ंक्शंस के लाभ के लिए उपलब्ध कराए जाते हैं। संभवतः एक इंटरफ़ेस-आधारित पायथन में, इन विधियों को एबीसी पर नियमित रूप से नामित विधियों में __len__ होगा, जिससे कि __len__ बन जाएगा

 class container: ... def len(self): raise NotImplemented 

यद्यपि, इसके बारे में कुछ और सोचकर, मुझे नहीं लगता कि सभी वाक्यविन्यास कार्रवाइयां सिर्फ एक विशिष्ट एबीसी पर सामान्य रूप से नामित विधि को क्यों नहीं लाती हैं। " < ", उदाहरण के लिए, संभवतः " object.lessthan " (या शायद " comparable.lessthanobject.lessthan ") को आह्वान करेगा। तो एक और फायदा होगा पायथन को इस गड़बड़ी-नाम विषमता से दूर करने की क्षमता, जो मुझे एक एचसीआई सुधार लगता है

हम्म। मुझे यकीन नहीं है कि मैं सहमत हूं (आंकड़ा 🙂

"पायथन तर्क" के दो टुकड़े हैं जो कि मैं सबसे पहले व्याख्या करना चाहता हूं।

सबसे पहले, मैंने एचसीआई के कारणों ( def __len__() लिए x.len () पर लैन (एक्स) चुना है)। वास्तव में दो intertwined कारण हैं, एचसीआई दोनों:

(ए) कुछ परिचालनों के लिए, उपसर्ग संकेतन सिर्फ पोस्टफ़िक्स – उपसर्ग (और इन्फिक्स!) के संचालन की तुलना में बेहतर पढ़ता है गणित में एक लंबी परंपरा है, जो उस अंकन पसंद करते हैं, जहां विज़िअल्स गणितज्ञ को किसी समस्या के बारे में सोचने में मदद करते हैं। आसान से तुलना करें जिसके साथ हम x*(a+b) x*a + x*b एक फार्मूला को फिर से लिखते हैं, जो कच्चे ओ ओ नोटेशन के उपयोग से एक ही बात करने की बेरहमी से है।

(बी) जब मैं len(x) कहता हूं कि कोड पढ़ता है, तो मुझे पता है कि यह कुछ की लंबाई के लिए पूछ रहा है यह मुझे दो चीजें बताता है: परिणाम एक पूर्णांक है, और तर्क किसी प्रकार का कंटेनर है इसके विपरीत, जब मैं x.len() पढ़ता हूं, तो मुझे पहले से ही पता x.len() होगा कि x किसी प्रकार का कंटेनर है जो मानक इंटरफ़ेस को लागू करता है या उस वर्ग से विरासत में ले जाता है जिसमें मानक len() । भ्रम की गड़बड़ी हम कभी-कभी करते हैं जब कोई ऐसा वर्ग जो मैपिंग को लागू नहीं कर रहा है get() या keys() पद्धति है, या ऐसी कोई चीज जो फ़ाइल नहीं है, उसे write() विधि है

दूसरी बात में एक ही बात कहने पर, मैं 'लेन' को एक निर्मित ऑपरेशन के रूप में देखता हूं। मुझे लगता है कि खोने के लिए नफरत है मैं यह सुनिश्चित करने के लिए नहीं कह सकता कि आप इसका मतलब है या नहीं, लेकिन 'डीईएफ लेनन (स्वयं): …' निश्चित रूप से ऐसा लगता है जैसे आप इसे एक साधारण तरीके से अवनत करना चाहते हैं मैं दृढ़ता से -1 हूं।

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

– – ग्वाडो वैन रॉसम (मुख पृष्ठ: http://www.python.org/~guido/ )

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

इस स्थिति में, मेरा अनुमान केवल ग्वाओ के पहले बिंदु पर आधारित get_king_moves को लागू करने के लिए होगा। लेकिन यह अभी भी बहुत से खुले प्रश्नों को छोड़ने के बारे में कहता है, एक समान ढक्कन और पॉप पद्धतियों के साथ एक स्टैक और कतार वर्ग को कार्यान्वित करना- क्या वे कार्य या विधियां हों? (यहां मुझे कार्य करने का अनुमान था, क्योंकि मैं वास्तव में एक पुश-पॉप इंटरफ़ेस संकेत करना चाहता हूं)

टीएलडीआर: क्या कोई ये बता सकता है कि कार्य बनाम तरीकों का उपयोग कब करना चाहिए, यह तय करने की रणनीति क्या होनी चाहिए?

Solutions Collecting From Web of "पायथन में, मुझे किसी विधि के बजाय फ़ंक्शन का उपयोग कब करना चाहिए?"

मेरा सामान्य नियम यह है – क्या ऑब्जेक्ट पर या ऑब्जेक्ट पर किया गया ऑपरेशन है?

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

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

 class duck: def __init__(self):pass def eat(self, o): pass def crap(self) : pass def die(self) .... 

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

 def kill(o): if isinstance(o, duck): o.die() elif isinstance(o, dog): print "WHY????" o.die() elif isinstance(o, nyancat): raise Exception("NYAN "*9001) else: print "can't kill it." 

इस सादृश्य से दूर चलना, हम तरीकों और वर्गों का उपयोग क्यों करते हैं? चूंकि हम डेटा समाहित करना चाहते हैं और उम्मीद है कि हमारे कोड को इस तरीके से ढाए जाएंगे कि यह भविष्य में पुन: प्रयोज्य और विस्तार योग्य होगा। यह हमें इनकैप्सुलेशन की कल्पना करने लाता है जो ओ ओ डिज़ाइन के लिए बहुत प्रिय है।

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

टीएल; डीआर : क्या @ ब्रायन ने कहा। यदि यह एक उदाहरण पर चल रहा है और डेटा का उपयोग करने की आवश्यकता है जो क्लास इंस्टेंस के लिए आंतरिक है, तो यह एक सदस्य फ़ंक्शन होगा।

जब आप चाहें तो एक कक्षा का उपयोग करें:

1) कार्यान्वयन के विवरण से कॉलिंग कोड अलग-अलग – अमूर्त और इनकैप्सुलेशन का लाभ उठाते हुए।

2) जब आप अन्य वस्तुओं के लिए प्रतिस्थापन करना चाहते हैं – बहुरूपता का लाभ उठाते हुए

3) जब आप समान वस्तुओं के लिए कोड का पुन: उपयोग करना चाहते हैं – विरासत का लाभ लेना।

कॉल के लिए एक फ़ंक्शन का उपयोग करें, जो कि कई अलग-अलग ऑब्जेक्ट प्रकारों में समझ में आता है – उदाहरण के लिए, बिल्टिन लेन और रिप ऑफ फ़ंक्शन कई प्रकार के ऑब्जेक्ट्स पर लागू होते हैं।

कहा जा रहा है, पसंद कभी कभी स्वाद के मामले के लिए नीचे आता है सामान्य कॉल के लिए सबसे सुविधाजनक और पठनीय क्या है इसके संदर्भ में सोचें। उदाहरण के लिए, जो बेहतर होगा (x.sin()**2 + y.cos()**2).sqrt() या sqrt(sin(x)**2 + cos(y)**2) ?

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

आपके विशिष्ट उदाहरण में, आप इसे इस तरह दिखना चाहते हैं:

 chessboard = Chessboard() ... chessboard.get_king_moves() 

इसके बारे में सोचो मत हमेशा तरीकों का उपयोग करें जब तक बात तब नहीं आती है जब आप अपने आप से कहते हैं कि "यह एक विधि बनाने में कोई मतलब नहीं है", इस स्थिति में आप एक फ़ंक्शन बना सकते हैं

मैं आमतौर पर एक व्यक्ति की तरह एक वस्तु के बारे में सोचता हूँ

गुण व्यक्ति का नाम, ऊंचाई, जूता आकार, इत्यादि हैं

तरीके और कार्य वह कार्य हैं जो व्यक्ति प्रदर्शन कर सकता है।

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

अगर कोई ऑपरेशन व्यक्ति (जैसे खाने, घूमना, …) पर कार्रवाई कर रहा है या इसमें शामिल होने के लिए कुछ विशिष्ट व्यक्ति की आवश्यकता है (जैसे नृत्य करना, कोई पुस्तक लिखना …), तो यह एक विधि होना चाहिए।

बेशक, यह आपके साथ काम कर रहे विशिष्ट वस्तु में इसका अनुवाद करने के लिए हमेशा तुच्छ नहीं होता, लेकिन मुझे लगता है कि इसके बारे में सोचने का एक अच्छा तरीका है।

आम तौर पर मैं कुछ चीजों के लिए क्षमताओं के एक तार्किक सेट को लागू करने के लिए कक्षाओं का उपयोग करता हूं, ताकि मेरे बाकी कार्यक्रम में मैं इस बात के बारे में सोच सकूं , इसका कार्यान्वयन करने वाली सभी छोटी चिंताओं की चिंता न करें।

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

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

यह उस कोड पर निर्भर करता है जो मैं लिख रहा हूं। कुछ कार्यक्रमों के लिए मैं उन वस्तुओं के संग्रह के रूप में उन्हें मॉडल करता हूं जिनके इंटरैक्शन कार्यक्रम के व्यवहार को जन्म देते हैं; यहां सबसे महत्वपूर्ण कार्यक्षमता को एक वस्तु के साथ मिलकर मिलकर जोड़ा जाता है, और इसी तरह से उपयोगिता कार्यों के बिखरने के साथ तरीकों में भी कार्यान्वित किया जाता है अन्य कार्यक्रमों के लिए सबसे महत्वपूर्ण चीजें कार्य का एक सेट होती हैं जो डेटा को हेरफेर करती हैं, और कक्षाओं का उपयोग केवल प्राकृतिक "बत्तख प्रकार" को कार्यान्वित करने के लिए किया जाता है जो फ़ंक्शन द्वारा छेड़छाड़ किए जाते हैं।