2010-03-05 14 views
14

मान लें कि मेरे पास class है, जो dict की कुछ कार्यक्षमता का उपयोग करता है। मैं अंदर dict ऑब्जेक्ट को मिश्रित करता था और बाहर से कुछ पहुंच प्रदान करता था, लेकिन हाल ही में dict को विरासत में लाने और कुछ विशेषताओं और विधियों को जोड़ने के बारे में सोचा जो मुझे चाहिए। क्या यह जाने का एक अच्छा तरीका है, या मुझे संरचना के साथ रहना चाहिए?पायथन: विरासत या रचना

उत्तर

13

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

सेविंग अग्रेषण कॉल आमतौर पर विरासत चुनने के लिए पर्याप्त कारण नहीं है।

डिजाइन पैटर्न पुस्तक से: वर्ग विरासत

से अधिक

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

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

पूरे पाठ यहाँ है: http://blog.platinumsolutions.com/node/129

+3

याद रखें कि पायथन बेहद लचीला है, ऑब्जेक्ट संरचना बहुत अच्छी है, लेकिन यदि आप सिर्फ एक से दूसरे ऑब्जेक्ट में मैपिंग कर रहे हैं, तो विरासत जाने का तरीका है। – voyager

+3

मुझे नहीं लगता कि पाइथन लचीला होने के साथ इसका कोई संबंध नहीं है, यह एक डिजाइन मुद्दा है। यदि आप एक ऑब्जेक्ट के सभी तरीकों को दूसरे पर मैप कर रहे हैं, तो आप शायद एक शब्दकोश बना रहे हैं: विरासत का उपयोग करें। लेकिन जब मूल पोस्टर लिखता है, "मेरे पास कक्षा है, जो कि कुछ की कार्यक्षमता का उपयोग करती है", यह इस तथ्य पर संकेत देती है कि कक्षा का उपयोग शब्दकोश के रूप में नहीं किया जाना है। –

+0

प्लैटिनम्सोल्यूशन का लिंक अब काम नहीं करता है ... आप संपादित करना चाहते हैं ... – unclejamil

3

दोनों अच्छे हैं, लेकिन मैं विरासत को प्राथमिकता देना चाहूंगा, क्योंकि इसका मतलब कम कोड होगा (जो तब तक हमेशा अच्छा होता है जब तक यह पठनीय नहीं होता)।

Dive into Python has a very relevant example

पायथन 2.2 और इससे पहले, आप सीधे अंतर्निहित इन्स से उपclass नहीं कर सके, इसलिए में संरचना का उपयोग करने के लिए था।

class FileInfo(dict):     
    "store file metadata" 
    def __init__(self, filename=None): 
     self["name"] = filename 
  1. पहले अंतर यह है कि आप के बाद से dict है UserDict मॉड्यूल आयात करने की आवश्यकता नहीं है एक अंतर्निहित डेटाप्रकार और हमेशा उपलब्ध है। दूसरी बात यह है कि आप UserDict.UserDict के बजाय सीधे निर्देश से विरासत में हैं।
  2. तीसरा अंतर सूक्ष्म लेकिन महत्वपूर्ण है। उपयोगकर्ताडिक्ट आंतरिक रूप से काम करने के तरीके के कारण, आपको इसकी आंतरिक डेटा संरचनाओं को ठीक से प्रारंभ करने के लिए मैन्युअल रूप से __init__ विधि को कॉल करने की आवश्यकता हैdict इस तरह काम नहीं करता है; यह एक रैपर नहीं है, और इसके लिए कोई स्पष्ट प्रारंभिक आवश्यकता नहीं है
3

आप वास्तव में लागत और तुम क्या करने की कोशिश कर रहे हैं क्या के दायरे से बाहर की तुलना करनी पड़ dict से विरासत क्योंकि आप चाहते हैं शब्दकोश की तरह व्यवहार बहुत तेज़ है। और आसान है लेकिन इस तरह अपनी कक्षा से बनाए गए वस्तुओं unhashable होने के लिए कारण के रूप में सीमाओं होने का खतरा।

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

3

isinstance(my_object, dict) सही या गलत वापसी करना चाहिए? दूसरे शब्दों में, यदि आप गलती से किसी ऑब्जेक्ट को dict चाहते हैं, तो क्या इसे dict के रूप में उपयोग करने का प्रयास करना चाहिए? शायद नहीं, तो रचना का उपयोग करें।

+0

लोगों की टाइपशेक की मदद करना एक अच्छी बात नहीं है। –

+0

टाइपिंग की जांच इसकी जगह है। उदाहरण के लिए, यदि आपके पास सुंदर प्रिंटर फ़ंक्शन था जो डिकट्स को समझता था, तो शायद आप इसे अपनी उन्नत ऑब्जेक्ट को प्रिंट नहीं करना चाहते थे जैसे कि यह एक नियम था। न ही आप चेक-फ्री विकल्प प्रकार का उपयोग करना चाहते हैं: बंदर पैचिंग dict। –

संबंधित मुद्दे