2011-12-19 3 views
36

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

  • http://www.python.org/dev/peps/pep-0316/ - पीईपी 316 कि अजगर के लिए अनुबंध जो टाल दिया गया है द्वारा डिजाइन का मानकीकरण करने माना जाता है। यह पीईपी डॉकस्ट्रिंग का उपयोग करने का सुझाव देता है।
  • http://www.wayforward.net/pycontract/ - पायथन के लिए अनुबंध। यह डॉकस्ट्रिंग का उपयोग कर एक पूर्ण, लेकिन अनियमित रूपरेखा प्रतीत होता है।
  • http://www.nongnu.org/pydbc/ - पीईडीबीसी जो मेटाक्लास का उपयोग करके अनुबंध लागू करता है। कुछ सालों के लिए भी अनियंत्रित।

मेरे प्रश्न हैं: क्या आपने परिपक्व उत्पादन कोड के लिए पाइथन के साथ डीबीसी का उपयोग किया है? यह कितना अच्छा काम करता है/क्या यह प्रयास के लायक था? आप किस उपकरण की सिफारिश करेंगे?

+0

ध्यान दें कि आप सिर्फ testcase से विरासत कर सकते हैं और किसी भी वर्ग में इकाई परीक्षण शामिल हैं। – Marcin

+3

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

+0

अनुबंध द्वारा डिज़ाइन वह जगह है जहां आप स्पष्ट रूप से उस विनिर्देश को निर्दिष्ट करते हैं जिसमें कोड का प्रत्येक भाग अनुरूप होता है। आपको इसे रनटाइम पर पूर्ण रूप से परीक्षण करने की आवश्यकता नहीं है। यूनिट परीक्षण उतना ही विनिर्देश हो सकता है जितना कुछ और। टीडीडी यूनिट परीक्षणों का उपयोग करने का एक अलग तरीका है, उस मामले में व्यवहार के अपेक्षित सेट को मॉडल करने के लिए। – Marcin

उत्तर

4

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

reddit में इस लाइब्रेरी के बारे में कुछ चर्चा हुई थी।

+1

यह एक अच्छा लग रहा है, लेकिन डीबीसी के एक बड़े हिस्से के लिए समर्थन की कमी है: कक्षा invariants। हालांकि मैं इसे ध्यान में रखूंगा। – ipartola

15

आपको जो पीईपी मिला है उसे अभी तक स्वीकार नहीं किया गया है, इसलिए ऐसा करने का मानक या स्वीकार्य तरीका नहीं है (फिर भी - आप हमेशा पीईपी को लागू कर सकते हैं!)। हालांकि, जैसा कि आपने पाया है, कुछ अलग-अलग दृष्टिकोण हैं।

शायद सबसे हल्का वजन केवल पाइथन सजावट का उपयोग करना है। Python Decorator Library में पूर्व-पोस्ट-स्थितियों के लिए सजावटकर्ताओं का एक सेट है जो उपयोग करने के लिए काफी सीधे हैं। यहां उस पृष्ठ से एक उदाहरण दिया गया है:

>>> def in_ge20(inval): 
    ... assert inval >= 20, 'Input value < 20' 
    ... 
    >>> def out_lt30(retval, inval): 
    ... assert retval < 30, 'Return value >= 30' 
    ... 
    >>> @precondition(in_ge20) 
    ... @postcondition(out_lt30) 
    ... def inc(value): 
    ... return value + 1 
    ... 
    >>> inc(5) 
    Traceback (most recent call last): 
    ... 
    AssertionError: Input value < 20 

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

+0

उत्तर के लिए धन्यवाद। मैं समझता हूं कि इसका उपयोग पायथन में डीबीसी को लागू करने के लिए किया जा सकता है। मैं क्या सोच रहा था कि क्या किसी ने पहले से वर्णित किसी भी पुस्तकालय या किसी अन्य पुस्तकालय के साथ सफलता प्राप्त की है। प्रश्न कम है "मैं डीबीसी कैसे कार्यान्वित करूं?" और अधिक "क्या मुझे डीबीसी लागू करने से परेशान होना चाहिए?"। – ipartola

+0

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

+1

@jcollado उल्लेख किए गए लिंक से अनुबंध पुस्तकालय (https://bitbucket.org/kisielk/covenant/) भी इनवेरिएंट है। – snim2

3

जबकि अनुबंध द्वारा डिज़ाइन नहीं किया गया है, तो कुछ परीक्षण ढांचे संपत्ति परीक्षण दृष्टिकोण के पक्ष में बहुत करीब हैं।

  • अपरिवर्तनशीलताओं इनपुट और आउटपुट मूल्यों
  • अन्य पूर्व की
  • डोमेन और postconditions

पायथन के लिए:

के लिए अगर कुछ गुण क्रम में पकड़ यादृच्छिक परीक्षण आसानी से जाँच करने के लिए अनुमति देता है कुछ क्विक चेक-स्टाइल परीक्षण ढांचे हैं:

9

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

class Math: 
    def square_root(self, number) 
     """ 
     Calculate the square-root of C{number} 

     @precondition: C{number >= 0} 

     @postcondition: C{abs(result * result - number) < 0.01} 
     """ 
     assert number >= 0 
     result = self._square_root(number) 
     assert abs(result * result - number) < 0.01 
     return result 

    def _square_root(self, number): 
     """ 
     Abstract method for implementing L{square_root()} 
     """ 
     raise NotImplementedError() 

मैं डिजाइन द्वारा अनुबंध सॉफ्टवेयर इंजीनियरिंग रेडियो (http://www.se-radio.net/2007/03/episode-51-design-by-contract/) पर पर एक प्रकरण से डिजाइन द्वारा अनुबंध की एक सामान्य उदाहरण के रूप में वर्गमूल मिला है। उन्होंने भाषा समर्थन की आवश्यकता का भी उल्लेख किया क्योंकि लिस्कोव-प्रतिस्थापन-सिद्धांत सुनिश्चित करने में दावा सहायक नहीं थे, हालांकि उपरोक्त मेरा उदाहरण अन्यथा प्रदर्शित करना है। मुझे प्रेरणा के स्रोत के रूप में सी ++ पिंपल (निजी कार्यान्वयन) मुहावरे का भी उल्लेख करना चाहिए, हालांकि इसका एक अलग उद्देश्य है।

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

बेहतर उपकरण समर्थन भविष्य में और भी अधिक शक्ति प्रदान कर सकता है, मुझे लगता है कि स्वागत करते हैं।

+0

महान उपाख्यान जो वास्तव में प्रश्न का उत्तर देता है। – doughgle

+0

अगर मैं गलत हूं तो मुझे सही करें, लेकिन यह वर्ग आविष्कारों के साथ अच्छा नहीं लगता है। आप उन्हें प्रत्येक पूर्व-और पोस्टकंडिशन में शामिल कर सकते हैं, लेकिन जब कोई विधि (1) इनविरिएंट को तोड़ती है तो वह झूठी सकारात्मक प्रतिक्रिया देगा (2) एक अन्य विधि को कॉल करता है जो invariant (3) को invariant (जिसे अनुमति है) को पुनर्स्थापित करता है। आप सार्वजनिक विधियों को कभी भी बुलाए जाने के अनुशासन को अपना सकते हैं, केवल निजी सहायकों को बुला सकते हैं, लेकिन फिर उन कॉल के लिए पूर्व और बाद की स्थितियों की जांच नहीं की जाएगी। – johncip

+0

यदि आपको ओवरराइडिंग निजी कार्यान्वयन पूर्व-या पोस्टकंडिशन अपडेट करता है, तो मुझे सार्वजनिक विधि को ओवरराइड करने की भी आवश्यकता है, लेकिन मुझे लगता है कि अभ्यास में यह एक बड़ा सौदा नहीं है, और निष्पक्ष होने के लिए मुझे नहीं पता कि अन्य उल्लिखित कार्यान्वयन इन मुद्दों को संभालते हैं इससे बेहतर नहीं हो सकता। – johncip