2016-03-22 8 views
16

पायथन में, क्या raise और raise e के बीच एक अंतर को छोड़कर कोई अंतर है?"raise" और "raise ई" के बीच अंतर?

dis मुझे अलग-अलग परिणाम दिखा रहा है, लेकिन मुझे नहीं पता कि इसका क्या अर्थ है।

दोनों का अंतिम व्यवहार क्या है?

import dis 
def a(): 
    try: 
     raise Exception() 
    except Exception as e: 
     raise 


def b(): 
    try: 
     raise Exception() 
    except Exception as e: 
     raise e 

dis.dis(a) 
# OUT: 4   0 SETUP_EXCEPT   13 (to 16) 
# OUT: 5   3 LOAD_GLOBAL    0 (Exception) 
# OUT:    6 CALL_FUNCTION   0 
# OUT:    9 RAISE_VARARGS   1 
# OUT:    12 POP_BLOCK   
# OUT:    13 JUMP_FORWARD   22 (to 38) 
# OUT: 6  >> 16 DUP_TOP    
# OUT:    17 LOAD_GLOBAL    0 (Exception) 
# OUT:    20 COMPARE_OP    10 (exception match) 
# OUT:    23 POP_JUMP_IF_FALSE  37 
# OUT:    26 POP_TOP    
# OUT:    27 STORE_FAST    0 (e) 
# OUT:    30 POP_TOP    
# OUT: 7   31 RAISE_VARARGS   0 
# OUT:    34 JUMP_FORWARD    1 (to 38) 
# OUT:   >> 37 END_FINALLY   
# OUT:   >> 38 LOAD_CONST    0 (None) 
# OUT:    41 RETURN_VALUE   
dis.dis(b) 
# OUT: 4   0 SETUP_EXCEPT   13 (to 16) 
# OUT: 5   3 LOAD_GLOBAL    0 (Exception) 
# OUT:    6 CALL_FUNCTION   0 
# OUT:    9 RAISE_VARARGS   1 
# OUT:    12 POP_BLOCK   
# OUT:    13 JUMP_FORWARD   25 (to 41) 
# OUT: 6  >> 16 DUP_TOP    
# OUT:    17 LOAD_GLOBAL    0 (Exception) 
# OUT:    20 COMPARE_OP    10 (exception match) 
# OUT:    23 POP_JUMP_IF_FALSE  40 
# OUT:    26 POP_TOP    
# OUT:    27 STORE_FAST    0 (e) 
# OUT:    30 POP_TOP    
# OUT: 7   31 LOAD_FAST    0 (e) 
# OUT:    34 RAISE_VARARGS   1 
# OUT:    37 JUMP_FORWARD    1 (to 41) 
# OUT:   >> 40 END_FINALLY   
# OUT:   >> 41 LOAD_CONST    0 (None) 
# OUT:    44 RETURN_VALUE   
+5

संभावित बहस [कोई तर्क के साथ उठाएं] (http://stackoverflow.com/questions/18001721/raise-with-no-argument) –

+1

@ जेरोम मुझे नहीं लगता कि यह इसका एक डुप्लिकेट है। यह प्रश्न इस विशिष्ट कोड नमूने में नो-Arg और with-arg संस्करणों के बीच अंतर के बारे में है। यह सवाल इस बात के बारे में है कि आम तौर पर नो-एर्ग कैसे काम करता है। वे संबंधित हैं लेकिन डुप्लिकेट – Daenyth

+0

हां नहीं, और स्वीकृत उत्तर इस कारण से दिलचस्प है। यदि कोई प्रश्न पूछने का कोई तरीका है, तो मैं करूँगा। –

उत्तर

14

इस मामले में कोई अंतर नहीं है। बिना तर्क के raisewill always raise the last exception thrown (जो sys.exc_info() के साथ भी पहुंच योग्य है)।

बाइटकोड अलग है क्योंकि पाइथन एक गतिशील भाषा है और दुभाषिया वास्तव में "पता नहीं" है कि e वर्तमान में संभाला जा रहा है (अनमोडिफाइड) अपवाद को संदर्भित करता है। लेकिन हमेशा ऐसा नहीं हो सकता है, पर विचार करें:

try: 
    raise Exception() 
except Exception as e: 
    if foo(): 
     e = OtherException() 
    raise e 

क्या e अब है? बाइटकोड संकलित करते समय बताने का कोई तरीका नहीं है (केवल जब प्रोग्राम प्रोग्राम चला रहा है)।

आपके जैसे सरल उदाहरणों में, पाइथन दुभाषिया के लिए बाइटकोड को "अनुकूलित" करने के लिए संभव हो सकता है, लेकिन अब तक कोई भी ऐसा नहीं कर पाया है। और उन्हें क्यों चाहिए? यह सबसे अच्छा माइक्रो-ऑप्टिमाइज़ेशन है और अभी भी अस्पष्ट स्थितियों में सूक्ष्म तरीकों से तोड़ सकता है। वहाँ है कि इस की तुलना में बहुत कम फांसी और अधिक बूट करने के लिए ;-)

+0

मैं अनुकूलित करने की कोशिश नहीं कर रहा हूँ, मैं सिर्फ अगर व्यवहार इस विशेष मामले – Daenyth

+1

@Daenyth हाँ, मैं समझता हूँ कि किसी भी अलग था सोच रहा था कि, अनुकूलन टिप्पणी की व्याख्या करने के कारण है कि अजगर में बाईटकोड "अनुकूलन" नहीं है केवल था सरल उदाहरण ;-) – Carpetsmoker

+0

आपका संपादन है कि और अधिक स्पष्ट करता है धन्यवाद – Daenyth

2

यह जानकारी sys.exc_clear() साथ "पिछले अपवाद" (यानी sys.exc_info() के परिणाम) स्पष्ट करने के लिए संभव है पौष्टिक होता है है अन्य फल का एक बहुत है। उदाहरण के लिए, यह तब होगा जब कैच ब्लॉक को foo() फ़ंक्शन कहा जाता है, जिसमें स्वयं को विशेष त्रुटि प्रबंधन होता है।

उस स्थिति में, raise तर्क के साथ और बिना किसी भिन्न अर्थ का अर्थ होगा। raise e में अभी भी कुछ पंक्तियों को पकड़े गए अपवाद का संदर्भ होगा, जबकि raise शॉर्टेंड None को बढ़ाने का प्रयास करेगा, जो एक त्रुटि है।

3

दो रूपों के उत्पन्न होने वाले बैकट्रैस में एक अंतर है।

raise का उपयोग करना, इस कोड:

Traceback (most recent call last): 
    File "myfile.py", line 2, in <module> 
    int("hello") 
ValueError: invalid literal for int() with base 10: 'hello' 

raise e का उपयोग करते हुए इस प्रकार है::

try: 
    int("hello") 
except ValueError as e: 
    raise 

निम्नलिखित पश्व-अनुरेखन देता

try: 
    int("hello") 
except ValueError as e: 
    raise e 

निम्नलिखित पश्व-अनुरेखन देता

+०१२३५१६४१०६१
Traceback (most recent call last): 
    File "myfile.py", line 4, in <module> 
    raise e 
ValueError: invalid literal for int() with base 10: 'hello' 

अंतर यह है कि raise मामले में, सही अपवाद के मूल स्रोत को संदर्भित लाइन पश्व-अनुरेखन में उद्धृत किया गया है है, लेकिन raise e मामले में ट्रैस बैक का संदर्भ raise e नहीं लाइन मूल कारण।

इसलिए, मैं हमेशा raise e के बजाय raise का उपयोग करने की सलाह देता हूं।

+0

व्यवहार आप का वर्णन कर रहे हैं अजगर 2 का सच है, लेकिन नहीं पायथन 3. अजगर 3 में, 'बढ़ा e' मूल स्रोत निगल नहीं है और वास्तव में सख्ती से पता चलता इस मामले में * अधिक * जानकारी। –

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