2010-03-26 14 views
19

कक्षा में त्रुटि-जांच करने का उचित तरीका क्या है? अपवाद उठा रहा है? एक इंस्टेंस वेरिएबल डिक्शनरी "त्रुटियों" को सेट करना जिसमें सभी त्रुटियां हैं और इसे वापस कर रहा है?चर सेट करने के दौरान पाइथन में त्रुटियों को बढ़ाने के लिए उचित तरीका

क्या कक्षा से त्रुटियों को मुद्रित करना बुरा है? क्या मुझे अपवाद उठाने पर झूठी वापसी करनी है?

बस यह सुनिश्चित करना चाहते हैं कि मैं सही काम कर रहा हूं। नीचे कुछ नमूना कोड है:

@property 
def password(self): 
    return self._password 

@password.setter 
def password(self,password): 
    # Check that password has been completed 
    try: 
     # Check that password has a length of 6 characters 
     if (len(password) < 6): 
      raise NameError('Your password must be greater \ 
          than 6 characters') 

    except NameError: 
     print 'Please choose a password' 
     return False 

    except TypeError: 
     print 'Please choose a password' 
     return False                                 

    #Set the password 
    self._password = password 

    #Encrypt the password 
    password_md5 = md5.new() 
    password_md5.update(password) 
    self._password_md5 = password_md5.hexdigest() 
+1

उस कोड में 'पासवर्ड' नाम की बहुत सारी चीज़ें। (पहला फ़ंक्शन, दूसरा फ़ंक्शन, और दूसरे फ़ंक्शन के लिए तर्क।) pyflakes आपका मित्र होगा। – keturn

+0

@keturn: यह 'संपत्ति()' फ़ंक्शन के लिए दस्तावेज़ों में दिखाया गया एक पैटर्न है। '.सेटर' सजावट का उपयोग करने वाले दस्तावेज़ों में [कोड उदाहरण] देखें (https://docs.python.org/3/library/functions.html#property)। सेटटर विधि 'पासवर्ड' के अंदर एक स्थानीय चर (पैरामीटर) है। अन्य नाम एक अलग नामस्थान में हैं (वे कक्षा से संबंधित हैं)। – jfs

उत्तर

28

आपका कोड एक संदर्भ से बाहर है इसलिए सही विकल्प स्पष्ट नहीं है।ValueError

  • NameError अपवाद का उपयोग न करें, यह केवल प्रयोग किया जाता है जब एक नाम, अपवाद ही कहा के रूप में, न कि स्थानीय या वैश्विक क्षेत्र में पाया जाता है, का उपयोग करें या TypeError यदि अपवाद चिंताओं: कुछ सुझाव के बाद पैरामीटर का मान या प्रकार;

  • त्रुटि संदेशों को मुद्रित न करें। एक सार्थक त्रुटि संदेश के साथ सार्थक अपवाद उठाएँ:

    raise ValueError("password must be longer than 6 characters") 
    
  • एक सेटर से एक मूल्य के रिटर्निंग व्यर्थ है, जबकि काम एक अभिव्यक्ति नहीं है यानि आप एक काम के मान की जाँच नहीं कर सकते हैं:

    if (user.password = 'short'): ... 
    
  • बस सेटर में एक अपवाद उठाएं और उस कोड को सेट करें जो संपत्ति को सेट करता है।

उदाहरण:

class Test: 

    minlen = 6 

    @property 
    def password(self): 
     return self._password 

    @password.setter 
    def password(self, value): 
     if not isinstance(value, basestring): 
      raise TypeError("password must be a string") 
     if len(value) < self.minlen: 
      raise ValueError("password must be at least %d character len" % \ 
           self.minlen) 
     self._password = value 

देखो भी this forms handling library में, वहाँ प्रमाणकों, here an example, अपने स्वयं में संस्थाओं कर रहे हैं: वे उच्च नियंत्रण और कम मिलकर कोड के साथ गतिशील रूप से सेट किया जा सकता है, लेकिन हो सकता है यह है आपको जरूरत से कहीं ज्यादा

+1

यह वास्तव में सहायक था। धन्यवाद। – ensnare

+0

@ एमजी, ग्रेट पोस्ट (और महान प्रारंभिक!) कुल मिलाकर, लेकिन मैं अंत में उदाहरण के बारे में चिंतित हूं। ऐसा लगता है कि आपने 'पासवर्ड' सजावट बनाई है, जिसका उपयोग बहुत अजीब है; क्या आपका मतलब '@ संपत्ति' है और पहली विधि 'पासवर्ड' नाम देना है? साथ ही, यदि आप गुणों का उपयोग करना चाहते हैं, तो आपको नए-शैली के वर्गों का उपयोग करना होगा, उदाहरण के लिए 'क्लास टेस्ट (ऑब्जेक्ट):' या किसी अन्य नई शैली शैली से उत्तराधिकारी के उदाहरण की पहली पंक्ति बदलें। (भले ही आप अभी तक गुणों का उपयोग नहीं कर रहे थे, आपको नए स्टाइल क्लासेस का उपयोग करना चाहिए।) –

+0

@ माइक ग्राहम: अरे, थकावट खराब चुटकुले खेल सकती है। आप संपत्ति नामकरण के लिए सही हैं, सटीक रूप वह है जिसे मूल रूप से प्रस्तुत किया जाता है, मैं पुरानी अच्छी 'पासवर्ड = संपत्ति (...)' पसंद करता हूं लेकिन मैं वास्तव में नए 2.6 वाक्यविन्यास को जानने के बिना उपस्थित होने के साथ सुसंगत हूं। दूसरा अवलोकन सत्य नहीं है: गुणों का उपयोग पुरानी स्टाइल कक्षाओं –

10

अजगर में एक त्रुटि संकेत के मानक तरीका एक अपवाद उठाते हैं और बुला कोड संभाल करते हैं यह करने के लिए है। या तो NameError & टाइपरर ऊपर की ओर ले जाएं, या उन्हें पकड़ें और एक अमान्य पासवर्ड अपवाद जिसे आप परिभाषित करते हैं।

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

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

4

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

एक सेटर के विशेष मामले में, उदाहरण के लिए, False लौटा रहा है या कुछ और मदद नहीं करेगा। आपके द्वारा जांचने के लिए आवृत्ति चर सेट करना बहुत उप-स्थानिक है, तब से आप दुर्घटना पर एक त्रुटि को याद कर सकते हैं।

print आमतौर पर किसी त्रुटि के लिए एक अच्छी प्रतिक्रिया नहीं है। इस मामले में, ऐसा लगता है कि आप अंतिम उपयोगकर्ता को बताना चाहते हैं कि उन्हें एक अलग पासवर्ड का उपयोग करने की आवश्यकता है। ऐसा लगता है कि आपको एक ऐसी विधि को कॉल करना चाहिए जो वेबपृष्ठ को फ़ॉर्म के साथ उपयोगकर्ता को समझाएगा कि क्या गलत हुआ; आप उस विधि को कॉल कर सकते हैं जो आपकी कक्षा में करता है या एक अपवाद उठाता है जो प्रसारित करेगा और अंततः उस उद्देश्य के लिए पकड़ा जाएगा और उपयोग किया जाएगा। (यह सामान्य सलाह है। मुझे आपको यह बताने के लिए पिलोन के बारे में पर्याप्त जानकारी नहीं है कि यह आपको यह कैसे करना चाहता है।)

आपको अपना खुद का NameError अपवाद नहीं उठाना चाहिए। NameError सुंदरम हमेशा आपके कार्यक्रम में एक टाइपो इंगित करता है, और इस तरह आप आमतौर पर इसे पकड़ना नहीं चाहते हैं। इसे पकड़कर, आप एक कार्यक्रम में अनावश्यक अनिश्चितता पेश करते हैं। ऐसा लगता है कि यह ValueError या उसके उपखंड (class InvalidPasswordError(ValueError): pass) की तरह कुछ और हो सकता है।

मुझे समझ में नहीं आता कि आप TypeError क्यों चेक करते हैं। आपको हमेशा यह समझना चाहिए कि आपके द्वारा पकड़े गए अपवाद के कारण क्या होगा। यदि आप इस मामले में करते हैं, तो यह बहुत अच्छा है; मैं यह नहीं समझ सकता कि TypeError में कौन सी त्रुटि बढ़ेगी, जिससे आप उपयोगकर्ता को संकेत देकर सौदा कर सकते हैं।

सादे टेक्स्ट में पासवर्ड प्राप्त करने और एमडी 5 हैश को संग्रहीत करने की आपकी तकनीक बहुत सुरक्षित नहीं है। आपको औथकिट जैसी कुछ चीज़ों को देखना चाहिए जो इस प्रक्रिया को और अधिक सुरक्षित और सार बना सकता है।

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