2014-11-04 4 views
9

मेरे कोड:के बारे में की कोशिश उलझन/कस्टम अपवाद को छोड़कर

class AError(Exception): 
    print 'error occur' 
for i in range(3): 
    try: 
     print '---oo' 
     raise AError 
    except AError: 
     print 'get AError' 
    else: 
     print 'going on' 
    finally: 
     print 'finally' 

जब मैं ऊपर कोड चलाने के लिए, उत्पादन यह है:

error occur 
---oo 
get AError 
finally 
---oo 
get AError 
finally 
---oo 
get AError 
finally 

मुझे लगता है कि स्ट्रिंग "error occur" तीन बार होने चाहिए, "---oo" की तरह, लेकिन यह केवल एक बार होता है; क्यूं कर?

उत्तर

11

Paul's answer स्पष्ट करने के लिए, यहाँ एक सरल उदाहरण है

Class being defined 
Instance being created 
Instance being created 
Instance being created 

कोड class परिभाषा के दायरे में है, लेकिन एक विधि def inition केवल एक बार चलाता है बाहर, जब वर्ग को परिभाषित किया जाता है।

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

class AError(Exception): 

    def __init__(self, *args, **kwargs): 
     Exception.__init__(self, *args, **kwargs) # call the superclass 
     print 'error occur' # print your message 

यह सुनिश्चित करता है कि उपवर्ग सुपर क्लास के लिए तर्कों का समर्थन करता है; Exception के मामले में, आप उदा। एक त्रुटि संदेश पारित: यदि आप इसे से परिचित नहीं हैं

>>> raise AError("Something went wrong.") 
error occur # your message gets printed when the instance is created 

Traceback (most recent call last): 
    File "<pyshell#11>", line 1, in <module> 
    raise AError("Something went wrong.") 
AError: Something went wrong. # the error message passes through to the traceback 

*args, **kwargs वाक्य रचना की एक विवरण के लिए, को देखने के जैसे What does ** (double star) and * (star) do for parameters?। सुपरक्लास विधियों को कॉल करने के लिए आप super का भी उपयोग कर सकते हैं, उदाहरण देखें Understanding Python super() with __init__() methods

+0

यह उत्तर बहुत स्पष्ट है, मुझे यह मिल गया है। 3 क्यू बहुत, तो आप की कंद! –

5

'error occur' पूरी कक्षा के लिए केवल एक बार मुद्रित हो जाता है।

शायद आपको उम्मीद है कि इसे बनाए गए वर्ग के प्रत्येक उदाहरण के लिए दौड़ने की उम्मीद है।

कि, क्या होने __init__ समारोह में रख लिए, जब AError का एक उदाहरण बन जाता है

class AError(Exception): 
    def __init__(self): 
     print 'error occur' 

__init__ कहा जाता है।

class Test(object): 

    print "Class being defined" 

    def __init__(self): 
     print "Instance being created" 


for _ in range(3): 
    t = Test() 

इस से व्यवहृत किया जा सकेगा:

+3

आप वर्ग परिभाषा और उदाहरण सृजन, यानी के बीच अंतर का उल्लेख करना चाहिए * क्यों * यह एक फर्क पड़ता है। इसके अतिरिक्त, '__init__' को तर्क लेना चाहिए और सुपरक्लस प्रारंभकर्ता को कॉल करना चाहिए, अन्यथा कस्टम त्रुटि का समर्थन नहीं करेगा उदा। एक त्रुटि संदेश। – jonrsharpe

+0

मैं दिशा देने के लिए कक्षा विधि और उदाहरण विधि, 3Q के बीच अंतर भूल गया। –

1

'error occur' स्ट्रिंग केवल एक दिखाई देती है क्योंकि पाइथन आपके AError कक्षा परिभाषा को पार्स करते समय निष्पादित करता है।

आप इसे आप अपने वर्ग का एक उदाहरण बनाने हर बार निष्पादित प्राप्त करना चाहते हैं, तो आप वर्ग के initialiser को परिभाषित करना होगा:

class AError(Exception): 
    def __init__(self): 
     print 'error occur' 

for i in range(3): 
    try: 
     print '---oo' 
     raise AError 
    except AError: 
     print 'get AError' 
    else: 
     print 'going on' 
    finally: 
     print 'finally' 

मज़ा (और भाषा के मैनुअल शायद पढ़ें ...)

+0

मेरा उत्तर देखें (और पॉल पर मेरी टिप्पणी) - 'एवरर .__ init__' को' अपवाद .__ init__' 'कॉल करना चाहिए और उचित तर्कों को संभालना चाहिए। – jonrsharpe

2

मैं दृढ़ता से अनुशंसा करता हूं कि आप अपने अपवाद, esp में कोई प्रिंट स्टेटमेंट न रखें।उनके रचनाकार नहीं! अपवाद अर्थपूर्ण संस्थाएं हैं और यदि आपको आवश्यकता हो तो आप उन्हें प्रिंट कर सकते हैं। यदि आपको प्रिंटिंग को स्वचालित रूप से logging या इसी तरह के पैकेज का उपयोग करना चाहिए।

क्या आप के बारे में पता नहीं हो सकता है कि आप ऐसा तरह except खंड में उपयोग के लिए अपवाद उदाहरण इकट्ठा कर सकते हैं:

class MyError(Exception): 
    pass 

for i in range(3): 
    try: 
     print '---oo' 
     raise MyError("error msg no. {}".format(i)) 
     # Exception usually always accept a string as their first parameter 
    except MyError, ex: 
     # Exception instance available inside the except clause as `ex` 
     print ex 
    else: 
     print 'going on' 
    finally: 
     print 'finally' 
संबंधित मुद्दे