2009-03-02 4 views
11

पायथन प्रकारों की जांच को हतोत्साहित करता है। लेकिन कई मामलों में यह उपयोगी हो सकता है:क्या मुझे कन्स्ट्रक्टर तर्कों के प्रकार (और अन्य स्थानों पर भी) जांचना चाहिए?

  1. जाँच हो रही है निर्माता तर्क। जैसे दुश्मन बूलियन, स्ट्रिंग, इत्यादि की जांच करना आदि। यदि मैं ऑब्जेक्ट के सदस्यों को तर्कों में नहीं डालता और सेट करता हूं तो इससे बाद में समस्याएं पैदा हो जाएंगी।

  2. कार्य तर्कों की जांच करना।

  3. गुणों में। अगर कोई गलत मान या अलग प्रकार सेट करता है, तो मुझे तुरंत जवाब देना चाहिए।

+0

पायथन प्रकार विफल रहता है - स्केल नहीं करता है; मैं मोनो का उपयोग करूंगा। –

उत्तर

9

सरल उत्तर नहीं है, बहुरूपता का उपयोग, अपवाद आदि

  1. निर्माता तर्क गलत प्रकार की जा रही है के मामले में, एक अपवाद है जब कोड को क्रियान्वित करने कि निर्भर फेंक दिया जाएगा एक विशेष प्रकार के पैरामीटर पर है। यदि यह एक अजीब, डोमेन विशिष्ट बात है, तो अपना खुद का अपवाद उठाएं। कोड के आसपास के ब्लॉक जो त्रुटियों को छोड़कर और त्रुटियों को संभालने में विफल होने की संभावना है। तो अपवाद हैंडलिंग का उपयोग करना बेहतर है। (फ़ंक्शन तर्कों के लिए भी जाता है)

  2. गुणों में, वही तर्क लागू होता है। यदि आप प्राप्त मूल्य को मान्य कर रहे हैं, तो इसकी सीमा जांचने के लिए एक दावा का उपयोग करें। यदि मान गलत प्रकार का है, तो यह वैसे भी असफल हो जाएगा। फिर, AssertionError संभाल लें।

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

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

नोट
एक निर्माता के लिए सामान्य, बुरा तर्क में कुछ के बारे में मैं बहुत ज्यादा चिंता नहीं है।

4

अपनी पसंद की जांच करें, आपको बस स्पष्ट होना है। निम्न उदाहरण मानक पुस्तकालय में a module से एक निर्माता है - यह extrasaction आर्ग की जाँच करता है:

class DictWriter: 
    def __init__(self, f, fieldnames, restval="", extrasaction="raise", 
       dialect="excel", *args, **kwds): 
     self.fieldnames = fieldnames # list of keys for the dict 
     self.restval = restval   # for writing short dicts 
     if extrasaction.lower() not in ("raise", "ignore"): 
      raise ValueError, \ 
       ("extrasaction (%s) must be 'raise' or 'ignore'" % 
       extrasaction) 
     self.extrasaction = extrasaction 
     self.writer = writer(f, dialect, *args, **kwds) 
11

जवाब लगभग हमेशा "नहीं"। पायथन, रूबी और कुछ अन्य भाषाओं में सामान्य विचार हमें "Duck Typing" कहा जाता है। आपको परवाह नहीं करना चाहिए कि कुछ क्या है, केवल यह कैसे काम करता है। दूसरे शब्दों में, "यदि आप चाहते हैं कि कुछ ऐसा है जो आपको क्वैक करता है, तो आपको यह जांचने की आवश्यकता नहीं है कि यह वास्तव में एक बतख है।"

वास्तविक जीवन में, उन सभी प्रकार के चेक में डालने की समस्या वैकल्पिक कार्यान्वयन के साथ इनपुट को प्रतिस्थापित करने में असमर्थता है। आप तानाशाह की जांच कर सकते हैं, लेकिन मैं कुछ ऐसा पास करना चाहता हूं जिसमें एक नियम नहीं है, लेकिन यह dict API लागू करता है।

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

एक और दृष्टिकोण है कि आप अपनी सहमति दे वयस्कों की तरह अपने एपीआई उपयोगकर्ताओं व्यवहार करना चाहिए, और सही ढंग से एपीआई का उपयोग करने उन पर भरोसा है। बेशक ऐसे समय होते हैं जब इनपुट जांच सहायक होती है, लेकिन यह आपके विचार से कम आम है। एक उदाहरण सार्वजनिक वेब से अविश्वसनीय स्रोतों से इनपुट है।

+0

मुझे वयस्कों की सहमति जैसे मेरे एपीआई उपयोगकर्ताओं पर भरोसा नहीं है। मैं जो कोड लिखता हूं उसे देखता हूं। –

+0

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

+0

यदि डेवलपर्स "वयस्कों की सहमति" नहीं कर सकते हैं तो उनकी समस्या है। जब तक एपीआई दस्तावेज़ मौजूद होते हैं, तो वे अपेक्षित तर्कों के प्रकारों की जांच कर सकते हैं, आप ठीक हैं। इसके अलावा आप विशेष रूप से एक निश्चित प्रकार का जवाब देना चाहते हैं। –

0

"यह समस्या बाद में कारण होगा अगर मैं नहीं करते हैं और तर्कों को वस्तु के सदस्यों की स्थापना की।"

कृपया "समस्याओं" जो बाद में कारण हो जाएगा की सही सूची पर बहुत स्पष्ट होना।

  • क्या यह बिल्कुल काम नहीं करेगा? ब्लॉक की कोशिश करने/छोड़ने के लिए क्या है।

  • यह "विचित्र रूप से" व्यवहार करेंगे? यह वास्तव में दुर्लभ है, और यह "पास-मिस" प्रकार और ऑपरेटरों तक ही सीमित है। मानक उदाहरण विभाजन है। यदि आप पूर्णांक की अपेक्षा करते हैं, लेकिन फ़्लोटिंग-पॉइंट प्राप्त करते हैं, तो विभाजन आप जो चाहते थे वह नहीं कर सकता है। लेकिन यह //, बनाम/विभाजन ऑपरेटरों के साथ तय है।

  • यह बस गलत हो जाएगा, लेकिन अभी भी पूरा करने के लिए दिखाई देते हैं? यह वास्तव में दुर्लभ है, और एक सुंदर सावधानी से तैयार किए गए प्रकार की आवश्यकता होगी जो मानक नामों का उपयोग करे, लेकिन गैर-मानक चीजें हों। उदाहरण

    लिए
    class MyMaliciousList(list): 
        def append(self, value): 
         super(MyMaliciousList, self).remove(value) 
    

उसके अलावा, यह चीजों को "कारण समस्याओं बाद में" के लिए मुश्किल है। कृपया "समस्या" के विशिष्ट उदाहरणों के साथ अपना प्रश्न अपडेट करें।

1

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

def my_sqrt(x): 
    assert x >= 0, "must be greater or equal to zero" 
    # ... 

अपने तर्क पर जोर दिया जाना अनुबंध से गरीब आदमी का डिजाइन की तरह है:

एक त्वरित और गंदे लेकिन उचित तरीका है अपने तर्क की जाँच करने के ज़ोर उपयोग करने के लिए है। (आप अनुबंध द्वारा डिज़ाइन देखना चाहते हैं; यह दिलचस्प है।)

1

AFAIU, आप यह सुनिश्चित करना चाहते हैं कि कुछ ऑब्जेक्ट वास्तविक उपयोग की तुलना में पहले के समय में "इंटरफ़ेस का पालन करें") व्यवहार करें। आपके उदाहरण में, आप जानना चाहते हैं कि ऑब्जेक्ट्स निर्माण समय पर उपयुक्त हैं, न कि वास्तव में जब उनका उपयोग किया जाएगा।

ध्यान में रखते हुए कि हम पाइथन से बात कर रहे हैं, मैं assert का सुझाव नहीं दूंगा (यदि python -O या पर्यावरण परिवर्तक PYTHONOPTIMIZE आपके प्रोग्राम के दौरान 1 पर सेट है?) या विशिष्ट प्रकार के लिए जाँच (क्योंकि है कि अनावश्यक रूप से प्रकार आप उपयोग कर सकते हैं) को प्रतिबंधित करता है, लेकिन मैं प्रारंभिक परीक्षण कार्यक्षमता, पंक्तियों के साथ कुछ सुझाव देगा:

def __init__(self, a_number, a_boolean, a_duck, a_sequence): 

    self.a_number= a_number + 0 

    self.a_boolean= not not a_boolean 

    try: 
     a_duck.quack 
    except AttributeError: 
     raise TypeError, "can't use it if it doesn't quack" 
    else: 
     self.a_duck= a_duck 

    try: 
     iter(a_sequence) 
    except TypeError: 
     raise TypeError, "expected an iterable sequence" 
    else: 
     self.a_sequence= a_sequence 

मैं इस सुझाव में try… except… else इस्तेमाल किया क्योंकि मैं चाहता हूँ उदाहरण सफल होने पर केवल सेट करें, यदि कोड सफल हो गया हो, भले ही कोड बदल दिया गया हो या बढ़ाया गया हो। जाहिर है, आपको ऐसा करने की ज़रूरत नहीं है।

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

0

जैसा कि डॉक कहते हैं, जवाब लगभग हमेशा "नहीं" होता है। पायथन में, आपको आमतौर पर परवाह नहीं है कि एक पैरामीटर एक निश्चित प्रकार है, लेकिन यह एक निश्चित प्रकार की तरह व्यवहार करता है। इसे "Duck Typing" के रूप में जाना जाता है। यह जांचने के दो तरीके हैं कि पैरामीटर किसी दिए गए प्रकार की तरह व्यवहार करता है: (1) आप इसका उपयोग कर सकते हैं जैसे कि आप अपेक्षा करते हैं और अपवाद फेंकते हैं/यदि यह नहीं होता है या (2) आप एक परिभाषित कर सकते हैं इंटरफ़ेस जो वर्णन करता है कि उस प्रकार को व्यवहार करना चाहिए और उस इंटरफ़ेस के साथ परीक्षण अनुरूप होना चाहिए।

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

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