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


118

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

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

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

मुझे जो उत्तर मिले वे काफी हद तक अनिर्णायक थे:

पायथन कुछ कार्यक्षमता के लिए तरीकों का उपयोग क्यों करता है (जैसे सूची.इंडेक्स ()) लेकिन अन्य के लिए कार्य करता है (जैसे लेन (सूची))?

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

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

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

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

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

अंत में, स्वयं Guido से :

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

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

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

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

"पायथन औचित्य" के दो टुकड़े हैं जिन्हें मैं पहले समझाना चाहता हूँ।

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

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

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

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

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

- - ग्यूडो वैन रोसुम (होम पेज: http://www.python.org/~guido/ )

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

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

TLDR: क्या कोई समझा सकता है कि कार्यों बनाम विधियों का उपयोग करते समय निर्णय लेने की रणनीति क्या होनी चाहिए?


2
मेह, मैंने हमेशा इस बारे में सोचा कि यह पूरी तरह से मनमाना है। बतख टाइपिंग "इंटरफेस" निहित करने की अनुमति देता है, इससे कोई फर्क नहीं पड़ता है कि आपके पास X.frobया X.__frob__स्वतंत्र है या नहीं frob
कैट प्लस प्लस

2
जबकि मैं ज्यादातर आपसे सहमत हूं, सिद्धांत रूप में आपका जवाब पायथोनिक नहीं है। स्मरण करो, "अस्पष्टता का सामना करने के लिए, अनुमान लगाने के प्रलोभन से इनकार करें।" (बेशक, समय सीमा इसे बदल देगी, लेकिन मैं इसे मज़ेदार / आत्म-सुधार के लिए कर रहा हूं।)
सीसर बॉतिस्ता

यह एक ऐसी चीज है जो मुझे अजगर के बारे में पसंद नहीं है। मुझे लगता है कि यदि आप एक स्ट्रिंग से एक इंट की तरह कास्ट टाइपिंग को मजबूर करने जा रहे हैं, तो बस इसे एक विधि बनाएं। परन्स और समय लेने में इसे घेरना कष्टप्रद है।
मैट

1
यह सबसे महत्वपूर्ण कारण है, जिसे मैं पायथन पसंद नहीं करता: आप कभी नहीं जानते कि आपको कुछ हासिल करना है या नहीं। और यह और भी अधिक जटिल हो जाता है जब आप नए पुस्तकालयों जैसे कि वैक्टर या डेटा फ्रेम के साथ अतिरिक्त पुस्तकालयों का उपयोग करते हैं।
वॉनजड

1
"पायथन का ज़ेन कहता है कि चीजों को करने का केवल एक ही तरीका होना चाहिए" सिवाय इसके कि नहीं।
बजे

जवाबों:


84

मेरा सामान्य नियम यह है - क्या ऑपरेशन ऑब्जेक्ट पर या ऑब्जेक्ट द्वारा किया जाता है?

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

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

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

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

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."

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

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

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


तो संक्षेप में, गैर-सदस्य कार्य अपरिवर्तनीय वस्तुओं पर काम करते हैं, उत्परिवर्तित वस्तुएं सदस्य-कार्यों का उपयोग करती हैं? (या यह एक सामान्यीकरण भी सख्त है? यह केवल कुछ कार्यों के लिए है क्योंकि अपरिवर्तनीय प्रकारों की कोई स्थिति नहीं है।)
सीज़र बॉतिस्ता

1
एक सख्त OOP दृष्टिकोण से मुझे लगता है कि उचित है। चूंकि पायथन के पास सार्वजनिक और निजी दोनों चर (__ में शुरू होने वाले नाम वाले चर) हैं और जावा के विपरीत शून्य गारंटीकृत एक्सेस सुरक्षा प्रदान करता है, इसलिए कोई पूर्णता नहीं है क्योंकि हम एक अनुमेय भाषा पर बहस कर रहे हैं। हालांकि जावा जैसी कम अनुमेय भाषा में, याद रखें कि getFoo () विज्ञापन सेटफू () फ़ंक्शन मानक हैं, इसलिए अपरिवर्तनीयता निरपेक्ष नहीं है। क्लाइंट कोड को केवल सदस्यों को असाइनमेंट करने की अनुमति नहीं है।
गिरफ्तारी

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

1
@CeasarBautista हाँ, बेन के पास एक बिंदु है। कोड डिजाइन के तीन "प्रमुख" स्कूल हैं 1) डिजाइन नहीं, 2) ओओपी और 3) कार्यात्मक। एक कार्यात्मक शैली में, कोई राज्य नहीं हैं। यह वह तरीका है जिसे मैं सबसे अधिक पायथन कोड को डिज़ाइन करते हुए देखता हूं, यह इनपुट लेता है और कुछ साइड-इफेक्ट्स के साथ आउटपुट उत्पन्न करता है। OOP की बात यह है कि सब कुछ एक राज्य है। कक्षाएं राज्यों के लिए एक कंटेनर हैं, और "सदस्य" फ़ंक्शन इसलिए राज्य-निर्भर और साइड-इफ़ेक्ट आधारित कोड हैं जो जब भी लागू होते हैं, तो कक्षा में परिभाषित राज्य को लोड करता है। अजगर दुबला कार्यात्मक के लिए जाता है, इसलिए गैर-सदस्य कोड की प्राथमिकता।
अर्कडेम

1
खाओ (स्वयं), बकवास (स्वयं), मरो (स्वयं)। हाहाहाहा
Wapiti

27

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

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

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

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

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

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


8

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

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

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

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


2
क्या आप बता सकते हैं कि आप फ़ंक्शन के तरीकों पर डिफ़ॉल्ट क्यों हैं? (और क्या आप समझा सकते हैं कि यह नियम अभी भी स्टैक और कतार / पॉप और पुश विधियों के मामले में समझ में आता है?)
सीज़र बॉतिस्ता

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

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

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

-1 इस जवाब के रूप में पूरी तरह से मनमाना है: आप अनिवार्य रूप से प्रदर्शित करने के लिए कि एक्स से वाई तुलना में बेहतर है कोशिश कर रहे हैं यह सोचते हैं कि एक्स वाई से बेहतर है
gented

7

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

विशेषताएँ व्यक्ति का नाम, ऊँचाई, जूते का आकार आदि हैं।

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

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

यदि कोई ऑपरेशन व्यक्ति पर कार्य कर रहा है (जैसे कि खाना, चलना, ...) या इसमें शामिल होने के लिए इस व्यक्ति को कुछ अनूठा करने की आवश्यकता है (जैसे नृत्य, किताब लिखना ...), तो यह एक तरीका होना चाहिए ।

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


लेकिन आप किसी भी पुराने व्यक्ति की ऊंचाई को माप सकते हैं, इसलिए उस तर्क से यह होना चाहिए height(person), नहीं person.height?
14

@endolith ज़रूर, लेकिन मैं कहूंगा कि ऊंचाई एक विशेषता के रूप में बेहतर है क्योंकि आपको इसे पुनः प्राप्त करने के लिए किसी भी फैंसी काम करने की आवश्यकता नहीं है। एक संख्या को पुनः प्राप्त करने के लिए एक फ़ंक्शन लिखना, अनावश्यक हूप्स के माध्यम से कूदने जैसा लगता है।
तेरह

@endolith दूसरी ओर, अगर वह व्यक्ति एक बच्चा है जो बढ़ता है और ऊंचाई बदलता है, तो यह स्पष्ट होगा कि एक विधि को ध्यान रखना चाहिए, न कि एक फ़ंक्शन।
7:14 पर थ्रिपथ

यह सच नहीं है। अगर आपके पास है तो are_married(person1, person2)क्या है यह क्वेरी बहुत सामान्य है और इस प्रकार एक फ़ंक्शन होना चाहिए और एक विधि नहीं होनी चाहिए।
पिथिकोस

@Pithikos ज़रूर, लेकिन इसमें एक ऑब्जेक्ट (व्यक्ति) पर की गई विशेषता या क्रिया से अधिक शामिल है, बल्कि दो वस्तुओं के साथ एक संबंध है।
13

4

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

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

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

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


0

आप कह सकते हैं कि, "अस्पष्टता का सामना करने के लिए, अनुमान लगाने के प्रलोभन से इनकार करें"।

हालांकि, यह भी एक अनुमान नहीं है। आपको पूरा यकीन है कि दोनों दृष्टिकोणों के परिणाम एक ही हैं कि वे आपकी समस्या को हल करते हैं।

मेरा मानना ​​है कि लक्ष्यों को पूरा करने के कई तरीके होना केवल एक अच्छी बात है। मैं विनम्रतापूर्वक आपको बताऊंगा, जैसा कि अन्य उपयोगकर्ताओं ने पहले ही किया था, जो कि "स्वाद बेहतर" को नियोजित करने के लिए / भाषा के संदर्भ में अधिक सहज महसूस करता है ।

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