अजगर में बतख टाइपिंग, डेटा सत्यापन और मुखर प्रोग्रामिंग


10

बतख टाइपिंग के बारे में :

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

तर्क सत्यापन के बारे में (ईएएफपी: अनुमति की तुलना में माफी के लिए पूछना आसान)। यहाँ से एक अनुकूलित उदाहरण :

... इसे करने के लिए अधिक पायथोनिक माना जाता है:

def my_method(self, key):
    try:
        value = self.a_dict[member]
    except TypeError:
        # do something else

इसका मतलब यह है कि आपके कोड का उपयोग करने वाले किसी अन्य व्यक्ति को वास्तविक शब्दकोश या उपवर्ग का उपयोग करने की आवश्यकता नहीं है - वे मैपिंग इंटरफ़ेस को लागू करने वाली किसी भी वस्तु का उपयोग कर सकते हैं।

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

मुखर प्रोग्रामिंग के बारे में :

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

उल्लिखित अवधारणाएं कभी-कभी संघर्ष में होती हैं, इसलिए मैं निम्नलिखित कारकों पर ध्यान देता हूं कि क्या मैं किसी भी डेटा सत्यापन को पूरा नहीं करता हूं, तो मजबूत सत्यापन करें या मुखर का उपयोग करें:

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

  2. मुखर प्रोग्रामिंग। यदि मेरा कोड नया है, तो मैं बहुत अधिक उपयोग करता हूं। इस पर आपकी क्या सलाह हैं? क्या आप बाद में कोड से दावे को हटा देते हैं?

  3. यदि मेरा कार्य / विधि एक एपीआई का हिस्सा नहीं है, लेकिन मेरे द्वारा लिखित, अध्ययन या परीक्षण किए गए एक अन्य कोड के माध्यम से इसके कुछ तर्क पारित करता है, तो मैं तथाकथित इंटरफ़ेस के अनुसार बहुत कुछ करता हूं। इसके पीछे मेरा तर्क - मेरे कोड में बेहतर फेल है, तो कहीं ना कहीं त्रुटि के साथ स्टैकट्रेस में 10 स्तर गहरा है जो कि बहुत अधिक डिबग करने के लिए मजबूर करता है और बाद में वैसे भी मेरे कोड में मुखर जोड़ देता है।

टाइप / वैल्यू वेलिडेशन, एसेर्स का उपयोग करने या न करने के लिए टिप्पणियाँ और सलाह? प्रश्न के सर्वोत्तम निरूपण के लिए क्षमा करें।

उदाहरण के लिए निम्नलिखित फ़ंक्शन पर विचार करें, जहां CustomerSQLAlchemy घोषणात्मक मॉडल है:

def add_customer(self, customer):
    """Save new customer into the database.
    @param customer: Customer instance, whose id is None
    @return: merged into global session customer
    """
    # no validation here at all
    # let's hope SQLAlchemy session will break if `customer` is not a model instance
    customer = self.session.add(customer)
    self.session.commit()
    return customer

इसलिए, सत्यापन को संभालने के कई तरीके हैं:

def add_customer(self, customer):
    # this is an API method, so let's validate the input
    if not isinstance(customer, Customer):
        raise ApiError('Invalid type')
    if customer.id is not None:
        raise ApiError('id should be None')

    customer = self.session.add(customer)
    self.session.commit()
    return customer

या

def add_customer(self, customer):
    # this is an internal method, but i want to be sure
    # that it's a customer model instance
    assert isinstance(customer, Customer), 'Achtung!'
    assert customer.id is None

    customer = self.session.add(customer)
    self.session.commit()
    return customer

बतख टाइपिंग, टाइप चेकिंग, डेटा सत्यापन के संदर्भ में आप इनमें से प्रत्येक का उपयोग कब और क्यों करेंगे?


1
जब तक कि प्रदर्शन के कारण
ब्रायन चेन

जवाबों:


4

मुझे कुछ मार्गदर्शक सिद्धांत दें।

सिद्धांत # १। जैसा कि http://docs.python.org/2/reference/simple_stmts.html में उल्लिखित है , डीबगिंग के लिए रहने के दौरान भी एसेर्स के प्रदर्शन को एक कमांड लाइन विकल्प के साथ हटाया जा सकता है। यदि प्रदर्शन एक समस्या है, तो ऐसा करें। मुखाग्नि छोड़ो। (लेकिन जोर से कुछ भी मत करो!)

सिद्धांत # २। यदि आप कुछ कर रहे हैं, और एक घातक त्रुटि होगी, तो एक मुखर का उपयोग करें। कुछ और करने में कोई मूल्य नहीं है। यदि बाद में कोई इसे बदलना चाहता है, तो वे आपके कोड को बदल सकते हैं या उस विधि कॉल से बच सकते हैं।

सिद्धांत # ३। किसी चीज को सिर्फ इसलिए न थोपें क्योंकि आपको लगता है कि यह करना बेवकूफी है। तो क्या हुआ अगर आपका तरीका तार के माध्यम से अनुमति देता है? अगर यह काम करता है, तो यह काम करता है।

सिद्धांत # ४। उन चीजों को अस्वीकार करें जो संभावित गलतियों के संकेत हैं। उदाहरण के लिए विचार करें कि विकल्पों का एक शब्दकोश पारित किया जा रहा है। यदि उस शब्दकोश में ऐसी चीजें हैं जो वैध विकल्प नहीं हैं, तो यह एक संकेत है कि कोई व्यक्ति आपके एपीआई को नहीं समझता था, या फिर कोई टाइपो था। उस पर उड़ाने से एक टाइपो को पकड़ने की अधिक संभावना है कि यह किसी को कुछ उचित करने से रोकने के लिए है।

पहले 2 सिद्धांतों के आधार पर, आपके दूसरे संस्करण को फेंक दिया जा सकता है। अन्य दो जो आप पसंद करते हैं वह स्वाद का मामला है। जो आपको अधिक संभावना लगता है? कि कोई व्यक्ति किसी गैर-ग्राहक को पास करेगा add_customerऔर चीजें टूट जाएंगी (जिस स्थिति में संस्करण 3 को प्राथमिकता दी जाती है), या यह कि कोई व्यक्ति किसी बिंदु पर अपने ग्राहक को किसी तरह की प्रॉक्सी वस्तु के साथ बदलना चाहता है जो सभी सही तरीकों से प्रतिक्रिया करता है (जिस स्थिति में संस्करण 1 को प्राथमिकता दी जाती है)।

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


मैं v.3 को पसंद करता हूं, विशेषकर जब इंटरफ़ेस डिजाइन करते हैं - नई कक्षाएं और विधियाँ लिखना। इसके अलावा, मैं एपीआई विधियों के लिए v.3 उपयोगी मानता हूं - क्योंकि मेरा कोड दूसरों के लिए नया है। मुझे लगता है कि मुखर दृष्टिकोण एक अच्छा समझौता है, क्योंकि यह अनुकूलित मोड में चलने पर उत्पादन में हटा दिया जाता है। > उस पर उड़ाने से एक टाइपो को पकड़ने की अधिक संभावना है कि किसी को कुछ उचित करने से रोकना है। <तो, आपको इस तरह के सत्यापन से कोई आपत्ति नहीं है?
वार्वारियुक

इसे इस तरह रख कर देखते हैं। मुझे लगता है कि विरासत में नक्शे खराब हैं कि मुझे डिजाइन कैसे विकसित करना पसंद है। मुझे रचना पसंद है। इसलिए मैं यह मानने से कतराता हूं कि यह उस वर्ग का है। लेकिन मैं उन दावों के विरोध में नहीं हूं जहां मुझे लगता है कि वे मुझे कुछ बचाते हैं।
btilly
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.